NSDecimalNumber (working with decimal numbers)

Mac OSX specific forum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

NSDecimalNumber (working with decimal numbers)

Post by wilbert »

OSX has a variable type named NSDecimal and a class named NSDecimalNumber to work with them.
There's also a number of C functions to work with NSDecimal numbers if speed is important.
An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.
Supported operations are addition, subtraction, multiplication, division, exponentiation and comparison.

Here's an example.

Code: Select all

; divide 1000 by 27.3

dn1 = CocoaMessage(0, 0, "NSDecimalNumber decimalNumberWithString:$", @"1e3")  ; 1000
dn2 = CocoaMessage(0, 0, "NSDecimalNumber decimalNumberWithString:$", @"27.3") ; 27.3
dn_result = CocoaMessage(0, dn1, "decimalNumberByDividingBy:", dn2)     ; 1000 / 27.3

Debug PeekS(CocoaMessage(0, CocoaMessage(0, dn_result, "stringValue"), "UTF8String"), -1, #PB_UTF8)


; multiply 8343958739834873983 by 9148374832787493749

dn1 = CocoaMessage(0, 0, "NSDecimalNumber decimalNumberWithString:$", @"8343958739834873983")
dn2 = CocoaMessage(0, 0, "NSDecimalNumber decimalNumberWithString:$", @"9148374832787493749")
dn_result = CocoaMessage(0, dn1, "decimalNumberByMultiplyingBy:", dn2)

Debug PeekS(CocoaMessage(0, CocoaMessage(0, dn_result, "stringValue"), "UTF8String"), -1, #PB_UTF8)


; present last result in scientific style

nf = CocoaMessage(0, 0, "NSNumberFormatter new")
CocoaMessage(0, nf, "setLocale:", CocoaMessage(0, 0, "NSLocale systemLocale"))
CocoaMessage(0, nf, "setNumberStyle:", 4); scientific style
fs = CocoaMessage(0, nf, "stringFromNumber:", dn_result)
CocoaMessage(0, nf, "release")
Debug PeekS(CocoaMessage(0, fs, "UTF8String"), -1, #PB_UTF8)
A second example (PB 5.40+)

Code: Select all

Procedure SetDecimalValue(*d.NSDecimal, value.s)
  ProcedureReturn CocoaMessage(0, CocoaMessage(0, 0, "NSScanner scannerWithString:$", @value), "scanDecimal:", *d) 
EndProcedure

Procedure SetDecimalValueQ(*d.NSDecimal, value.q)
  If value < 0
    *d\_bitFields = $3400
    *d\_mantissa[0] = -value
  Else
    *d\_bitFields = $2400
    *d\_mantissa[0] = value
  EndIf
  *d\_mantissa[1] = 0
EndProcedure

SetDecimalValueQ(@dv1.NSDecimal, 8282121271218791812)
SetDecimalValueQ(@dv2.NSDecimal, 7372627637236212363)

NSDecimalMultiply_(@dv1, @dv1, @dv2, #NSRoundPlain)
ds = NSDecimalString_(@dv1, #nil)

MessageRequester("NSDecimal multiplication", PeekS(CocoaMessage(0, ds, "UTF8String"), -1, #PB_UTF8))
Windows (x64)
Raspberry Pi OS (Arm64)