如何使用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; 

如果你只是想从一个floatint常量的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议来确保你在十进制中的安全。

Interesting Posts