NSDecimalNumber到unsignedLongLong - 错误的值

时间:2010-07-21 11:13:35

标签: iphone core-foundation

这是代码:

NSNumber* number = [NSDecimalNumber decimalNumberWithString :@"11111111111111111"];
NSLog(@"%@ = %lld", number, [number unsignedLongLongValue]);

我得到输出:

11111111111111111 = 11111111111111112

它是否已知错误或我做错了什么?

更新 报告错误:https://bugreport.apple.com/cgi-bin/WebObjects/RadarWeb.woa/3/wo/Stnn5Aaocknzx52c64zbN0/5.83.28.0.9

1 个答案:

答案 0 :(得分:2)

我认为问题在于您在NSDecimalNumber上使用NSNumber的-longLongValue方法。 NSDecimalNumber在内部以十进制形式存储数字的高精度表示,但NSNumber仅将其保留为IEEE 754双精度浮点值。如果我没记错的话,如果在NSDecimalNumber上使用标准的NSNumber超类方法,内部编号首先会转换为double,这会引入像这样的二进制浮点工件。

正如neoneye建议的那样,解决这个问题的方法可能是使用NSString作为中介。例如:

NSDecimalNumber* number = [NSDecimalNumber decimalNumberWithString :@"11111111111111111"];
double number2 = [@"11111111111111111" doubleValue];

NSLog(@"%@ = %lld = %f", number, [[number descriptionWithLocale:nil] longLongValue], number2);

将生成结果11111111111111111 = 11111111111111111 = 11111111111111112.000000,显示十进制数字提取的正确结果以及此数字临时存储在双精度中时发生的错误。