我有一个 NSDictionary,其中包含一个值为 4937446359977427944 的键。我尝试将它的值设置为 long long 并返回 4937446359977427968?
NSLog(@"value1 = %@", [dict objectForKey"MyKey"]); // prints 4937446359977427944
long long lv = [dict objectForKey:@"MyKey"] longLongValue];
NSLog(@"value2 = %lld", lv); // prints 4937446359977427968
正在做:
NSLog(@"%lld", [@"4937446359977427944" longLongValue]); // prints 4937446359977427944
我假设这是某种舍入问题,因为低位似乎已被清除,我只是不知道如何阻止它(或者为什么会发生)。
正在使用 NSJSONSerialization
创建字典,并且 JSON 对象确实(正确地)包含 "MyKey": 4937446359977427944
条目和 dict
对象是正确的。
保存在 NSDictionary
中的值是一个 NSDecimalNumber
是否有东西在幕后转换为 float ?
最佳答案
NSDecimalValue
未存储为 double
,它是一个 64 位无符号整数尾数,一个以 10 为底的 8 位有符号整数指数,和一个符号位。
问题是 NSDecimalValue
的精确值只能表示为... NSDecimalValue
.
您可以使用方法 doubleValue
获得大约 64 位的 IEE754 值.
当您尝试使用 longLongValue
时您可以有效地获得转换为 long long int 的近似 IEE754 值的结果。
您可能会或可能不会认为它是 NSDecimalValue
实现中的错误(并最终提交雷达并要求 Apple 使用不同的转换例程)。但严格来说,这不是错误:这是一个设计决定。
你应该想到NSDecimalValue
作为一种浮点小数。事实上,它非常类似于 IEEE754 称之为扩展精度浮点十进制数的软件实现,只是它不符合该定义(因为它没有支持至少值的指数在 −6143 和 +6144 之间,因为它不支持 NAN 和无穷大)。
换句话说,它不是整数的扩展实现,而是 double 的扩展(但缺少 NAN 和无限)实现。事实上,Apple native 只提供对 double
的近似转换。 (暗示对于超过 53 位精度的任何值,转换为 long long int 可能准确也可能不准确)不是错误。
您可能想也可能不想自己实现不同的转换(使用类别)。
另一种可能的观点是将问题视为您使用的 JSon 实现中的错误。但这也很有争议:它给了你一个 NSDecimalValue
这可以说是正确的表示。您要么使用 NSDecimalValue
操作或您对它的任何转换负责。
关于objective-c - 为什么 longLongValue 返回不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12418224/