ios – 在Swift中将Double转换为NSNumber失去准确性

ios – 在Swift中将Double转换为NSNumber失去准确性,第1张

概述参见英文答案 > Is floating point math broken?                                    27个 出于某种原因,我的Swift应用程序中的某些双打在转换为NSNumber时会给我带来麻烦,而有些则不然.我的应用程序需要将2位小数(价格)的双精度转换为NSNumbers,以便使用Core Data存储和检索它们.例如,除非使用NSNumbe 参见英文答案 > Is floating point math broken?27个
出于某种原因,我的Swift应用程序中的某些双打在转换为NSNumber时会给我带来麻烦,而有些则不然.我的应用程序需要将2位小数(价格)的双精度转换为NSNumbers,以便使用Core Data存储和检索它们.例如,除非使用NSNumber的doubleValue方法进行特殊格式化,否则一些特定的价格(例如79.99)将评估为99.98999999999999.

这里选择了Warranty.price = 79.99,如调试器中所示

// item.price: NSNumber?       // selecteDWarranty.price: Double?  item.price = NSNumber(double: selecteDWarranty.price!)

我编写了一些打印语句来说明转换是如何工作的

Original double: 79.99Converted to NSNumber: 79.98999999999999.doubleValue Representation: 79.99

有人可以解释一下,为什么初始化器不能确保为每个数字保留2个小数位?我真的希望将价格存储在核心数据中.每次显示时格式化都听起来不太方便.

更新:
转换的核心数据对象通过数据模型输入NSDecimalNumber,79.99和99.99不再是问题,但现在更易于管理的问题与不同的数字…

Original double: 39.99Converted to NSDecimalNumber: 39.99000000000001024
解决方法 首先,你会混淆一些条款. 79.98999999999999的精度高于79.99(它具有较长的十进制扩展),但精度较低(它偏离真实值).

其次,NSNumber既不存储79.99也不存储79.98999999999999.它根据IEEE 754标准存储值的大小.您所看到的可能是印刷逻辑的结果,该逻辑用于将该幅度转换为人类可读数字.在任何情况下,您都不应该依赖float或Double来存储具有固定精度的值.就其本质而言,他们牺牲精确度以获得更长范围的可表示值.

将价格表示为美分的Int或NSDecimalNumber会更好.

请参考Why not use Double or Float to represent currency?

总结

以上是内存溢出为你收集整理的ios – 在Swift中将Double转换为NSNumber失去准确性全部内容,希望文章能够帮你解决ios – 在Swift中将Double转换为NSNumber失去准确性所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1105770.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存