带有2个小数点的NSNumberFormatter会导致奇怪的结果

时间:2016-02-01 23:21:57

标签: ios objective-c

我尝试将float值转换为string并使用NSNumberFormatter。我做了一个舍入函数并使用格式化程序进行字符串表示。格式化程序只应该使用语言环境和小数符号。我最终得到了错误的价值。

的结果
NSNumberFormatter *_numberFormatter = [[NSNumberFormatter alloc] init];
[_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[_numberFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"de_DE"]];
[_numberFormatter setMaximumFractionDigits:2];
[_numberFormatter setRoundingMode: NSNumberFormatterRoundDown];
NSString* sumString = [_numberFormatter stringFromNumber:[NSNumber numberWithFloat:14.2f]];

是'14,19'。我不明白为什么当小数点只有1时,该值会向下舍入。舍入模式在这里什么都不做,或者我错了。我可以使用'NSNumberFormatterRoundUp',但在某些情况下结果可能是'14,21'?

2 个答案:

答案 0 :(得分:4)

这里的问题是base-2浮点数(这是所有Apple平台使用的)不能完全代表实数14.2。最接近的双精度浮点数恰好是14.199999999999999289457264239899814128875732421875。如您所见,这略低于14.2。

您指定了NSNumberFormatterRoundDown舍入模式。这意味着格式化程序将打印符合您的格式的最大数字(两个小数位),并且小于或等于输入数字。两个小数位小于或等于14.199999999999999289457264239899814128875732421875的最大十进制数是14.19。

如果您正在处理货币价值,您可能需要查看NSDecimalNumberNSDecimalNumberdouble慢得多,但它是一个基数为10的浮点格式,因此它可以完全代表14.2。

答案 1 :(得分:1)

NSNumberFormatterRoundDown替换为NSNumberFormatterRoundHalfUp

NSNumberFormatterRoundDown: 向零回合。

NSNumberFormatterRoundHalfDown: 向最近的整数舍入,如果等距,则向零舍入。