How to use NSDecimalNumber?

I am creating an application that is supposed to do money calculations.

I wonder how to use NSDecimalNumber correctly, especially how to initialize it from integers, floats and doubles?

It was easy for me to use the -decimalNumberWithString: method. The methods -initWith... discouraged, so that they are only left with the mantissa, but never in any of the 7 languages ​​I used before, I need it, so I don’t know what was there ...

+43
math cocoa
Jan 17 '09 at 17:50
source share
3 answers

Do NOT use the NSNumber +numberWith... methods to create NSDecimalNumber objects. They are declared as returned NSNumber objects and cannot function as instances of NSDecimalNumber .

This is explained in this thread by Bill Bumgarner, an Apple developer. I would advise you to indicate an error in this behavior, referring to the error rdar: // 6487304.

Alternatively, these are all suitable methods for creating an NSDecimalNumber :

 + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag; + (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm; + (NSDecimalNumber *)decimalNumberWithString:(NSString *)numberValue; + (NSDecimalNumber *)decimalNumberWithString:(NSString *)numberValue locale:(id)locale; + (NSDecimalNumber *)zero; + (NSDecimalNumber *)one; + (NSDecimalNumber *)minimumDecimalNumber; + (NSDecimalNumber *)maximumDecimalNumber; + (NSDecimalNumber *)notANumber; 

If you just want NSDecimalNumber from a float or int constant to try something like this:

 NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal: [[NSNumber numberWithFloat:2.75f] decimalValue]; 
+80
Jan 18 '09 at 3:01
source share

The correct way is to do this:

 NSDecimalNumber *floatDecimal = [[[NSDecimalNumber alloc] initWithFloat:42.13f] autorelease]; NSDecimalNumber *doubleDecimal = [[[NSDecimalNumber alloc] initWithDouble:53.1234] autorelease]; NSDecimalNumber *intDecimal = [[[NSDecimalNumber alloc] initWithInt:53] autorelease]; NSLog(@"floatDecimal floatValue=%6.3f", [floatDecimal floatValue]); NSLog(@"doubleDecimal doubleValue=%6.3f", [doubleDecimal doubleValue]); NSLog(@"intDecimal intValue=%d", [intDecimal intValue]); 

More details here .

+29
Mar 14 2018-11-11T00:
source share

Think about it, you should try to avoid converting NSDecimalNumber or NSDecimals to and from int, float, and double values ​​for the same reasons that NSDecimalNumbers is recommended: loss of precision and binary floating point problems. I know sometimes this is inevitable (taking input from a slider, doing trigonometric calculations, etc.), but you should try to take data from users as NSStrings, and then use initWithString: locale: or decimalNumberWithString: locale: to generate NSDecimalNumbers. Do all your math with NSDecimalNumbers and return your view to users or save them in SQLite (or everywhere) as their string description using descriptionWithLocale :.

If you need to enter data from int, float or double, you can do something like the following:

 int myInt = 3; NSDecimalNumber *newDecimal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", myInt]]; 

or you could follow Ashley's suggestion to make sure you are safe in decimal.

+6
Jan 19 '09 at 16:20
source share



All Articles