将'浮动'转换为NSNumber,返回'浮动'的精度损失

Cra*_*tis 9 floating-point cocoa objective-c nsnumber

我似乎在Objective-C中遇到一个奇怪的问题,将浮点数转换为NSNumber(为方便起见将其包装),然后将其转换回浮点数.

简而言之,我的一类有一个属性red,这是一个浮动0.01.0:

@property (nonatomic, assign) float red;
Run Code Online (Sandbox Code Playgroud)

此对象将自身与从磁盘加载的值进行比较,以进行同步.(该文件可以在应用程序之外进行更改,因此它会定期检查文件更改,将备用版本加载到内存中,并进行比较,合并差异.)

这是一个有趣的片段,其中比较了两个值:

if (localObject.red != remoteObject.red) {
    NSLog(@"Local red: %f Remote red: %f", localObject.red, remoteObject.red);
}
Run Code Online (Sandbox Code Playgroud)

这是我在日志中看到的内容:

2011-10-28 21:07:02.356 MyApp[12826:aa63] Local red: 0.205837 Remote red: 0.205837
Run Code Online (Sandbox Code Playgroud)

奇怪的.对?这段代码是如何执行的?

存储在文件中的实际值:

...red="0.205837"...
Run Code Online (Sandbox Code Playgroud)

转换为float使用:

currentObject.red = [[attributeDict valueForKey:@"red"] floatValue];
Run Code Online (Sandbox Code Playgroud)

在代码的另一个点上,我能够从GDB中截取屏幕截图.它被打印到NSLog中:(这也是它在磁盘上的文件中显示的精度.)

2011-10-28 21:21:19.894 MyApp[13214:1c03] Local red: 0.707199 Remote red: 0.707199
Run Code Online (Sandbox Code Playgroud)

但在调试器中显示为:

GDB截图

如何在属性级别获取此级别的精度,但不是存储在文件中,还是在NSLog中正确打印?为什么它似乎变化了?

cho*_*own 5

如果您在任何时候将其转换为字符串或从字符串转换,请尝试使用%0.16f而不是%f(或者您想要的任何精度而不是.16).

有关详细信息,请参阅IEEE标准格式.


另外,使用objectForKey而不是valueForKey(valueForKey不打算在字典上使用):

currentObject.red = [[attributeDict objectForKey:@"red"] floatValue];
Run Code Online (Sandbox Code Playgroud)

有关objectForKeyvs 的更好解释,请参阅此SO答案valueForKey:

objectForKey和valueForKey之间的区别?