我正在构建一个需要对资金进行计算的应用程序。
我想知道如何正确使用NSDecimalNumber,特别是如何从整数,浮动和放大器初始化它。双打?
我发现使用-decimalNumberWithString:
方法很容易。不鼓励使用-initWith...
方法,只留下带有尾数的方法,但从来没有使用过我以前用过的7种语言中的任何一种语言,所以我不知道是什么放在那里......
答案 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]];