如何使用NSDecimalNumber?
我正在构build一个需要对金钱进行计算的应用程序。
我不知道如何正确使用NSDecimalNumber,特别是如何从整数,浮点数和双精度来初始化它?
我只发现使用-decimalNumberWithString:
方法很容易。 -initWith...
方法是不鼓励的,所以只留下尾数,但从来没有使用过我以前使用过的7种语言中的任何一种,所以我不知道放在那里的是什么…
不要使用NSNumber
的+numberWith...
方法来创buildNSDecimalNumber
对象。 它们被声明为返回NSNumber
对象,不能保证作为NSDecimalNumber
实例。
苹果公司的开发者Bill Bumgarner在本篇主题中解释了这一点。 我鼓励你提交一个对这个行为的bug,引用bug rdar:// 6487304。
作为替代,这些都是用来创buildNSDecimalNumber
所有适当的方法:
+ (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;
如果你只是想从一个float
或int
常量的NSDecimalNumber
尝试这样的事情:
NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithDecimal: [[NSNumber numberWithFloat:2.75f] decimalValue];
正确的方法实际上是这样做的:
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]);
在这里看到更多信息。
在devise方面,您应该尽量避免将NSDecimalNumber或NSDecimals转换为int,float和double值,原因与build议您使用NSDecimalNumbers的原因相同:丢失精度和二进制浮点表示法问题。 我知道,有时它是不可避免的(从一个滑块input数据,做三angular函数计算等),但是你应该尝试从用户那里inputNSString,然后使用initWithString:locale:或者decimalNumberWithString:locale:来生成NSDecimalNumbers。 用NSDecimalNumbers完成所有的math运算,然后使用descriptionWithLocale:作为string描述将它们的表示forms返回给用户或者保存到SQLite(或者任何地方)。
如果您必须从int,float或doubleinput,则可以执行以下操作:
int myInt = 3; NSDecimalNumber *newDecimal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", myInt]];
或者你可以按照阿什利的build议来确保你在十进制中的安全。