objective-c - 为什么 longLongValue 返回不正确的值

标签 objective-c

我有一个 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/

相关文章:

ios - 从 iOS 发送 JSON,奇怪的响应

objective-c - NSTextContainer 排除路径 setter 无法识别?

objective-c - 从 Objective-C 运行 shell 脚本

ios - 在 Swift 中为 XYPieChart 设置值

ios - 在自己的静态框架中添加 Realm objc 文件

ios - 应用程序在 [__NSCFDictionary setObject :forKey:] in iOS 9 only 处崩溃

ios - 当 NSDate 为 nil 时,NSDateFormatter 返回(空)字符串

ios - 解析函数 `findObjectsInBackgroundWithBlock:` 检索部分数据库对象,但不是全部

objective-c - XIB 文件的 iOS Localizable.strings 文件?

iOS : How can I set frame of UILabel according to its text?