如何使用NSDecimalNumber?

时间:2009-01-17 17:50:35

标签: cocoa math

我正在构建一个需要对资金进行计算的应用程序。

我想知道如何正确使用NSDecimalNumber,特别是如何从整数,浮动和放大器初始化它。双打?

我发现使用-decimalNumberWithString:方法很容易。不鼓励使用-initWith...方法,只留下带有尾数的方法,但从来没有使用过我以前用过的7种语言中的任何一种语言,所以我不知道是什么放在那里......

4 个答案:

答案 0 :(得分:82)

使用NSNumber的{​​{1}}方法创建+numberWith...个对象。它们被声明为返回NSDecimalNumber个对象,并不保证可以作为NSNumber个实例运行。

Apple的开发人员Bill Bumgarner在此thread中对此进行了解释。我鼓励你提出一个针对这种行为的bug,引用bug rdar:// 6487304。

作为替代方案,这些是用于创建NSDecimalNumber的所有适当方法:

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; NSDecimalNumber常量的float,请尝试以下操作:

int

答案 1 :(得分:31)

实际上,正确的方法是这样做:

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]);

查看更多信息here

答案 2 :(得分:6)

在设计方面,您应该尽量避免将NSDecimalNumber或NSDecimals转换为int,float和double值,原因与推荐使用NSDecimalNumbers的原因相同:精度损失和二进制浮点表示问题。我知道,有时它是不可避免的(从滑块输入,进行三角计算等),但你应该尝试从用户那里获取输入作为NSStrings然后使用initWithString:locale:或decimalNumberWithString:locale:来生成NSDecimalNumbers。使用NSDecimalNumbers完成所有数学运算并将其表示返回给用户,或使用descriptionWithLocale将它们保存到SQLite(或任何地方)作为其字符串描述:。

如果必须输入int,float或double,则可以执行以下操作:

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

或者你可以按照Ashley的建议来确保你在十进制结构中是安全的。

答案 3 :(得分:0)

一个小附加功能:如果您从字符串中初始化NSDecimalNumber,则也可以设置一个区域设置。例如,如果您的字符串包含逗号作为decimal separator

self.order.amount = [NSDecimalNumber decimalNumberWithString:self.amountText locale:[NSLocale currentLocale]];