How to use NSDecimalNumber?

cocoa, math

Solution

Do NOT use `NSNumber`'s `+numberWith...` methods to create `NSDecimalNumber` objects. They are declared to return `NSNumber` objects and are not guaranteed to function as `NSDecimalNumber` instances.

This is explained in this thread by Bill Bumgarner, a developer at Apple. I would encourage you to file a bug against this behavior, referencing bug rdar://6487304.

As an alternative these are all of the appropriate methods to use to create 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 simply want an `NSDecimalNumber` from a `float` or `int` constant try something like this:

NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal:
                             [[NSNumber numberWithFloat:2.75f] decimalValue];

Problem

I'm building a app that needs to perform calculations on money. I wonder how to properly use NSDecimalNumber, especially how to initialize it from integers, floats & doubles? I only found it easy to use the `-decimalNumberWithString:` method. The `-initWith...` methods are discouraged so that only left the ones with mantissa, but never in any of 7 languages I used before did I need that so I don't know what put there...

Original source