This question already has answers here:
Is floating point math broken?
(30个答案)
4年前关闭。
出于某种原因,我的Swift应用程序中的某些Doubles在转换为NSNumber时给了我麻烦,而有些则没有。我的应用程序需要将具有2个小数位(价格)的 double 数转换为NSNumbers,以便可以使用Core Data进行存储和检索。例如,除非使用NSNumber的doubleValue方法进行特殊格式设置,否则某些特殊价格(例如79.99)将评估为99.98999999999999。
在这里,selectedWarranty.price = 79.99,如调试器中所示
我编写了一些打印语句,以显示转换如何进行
有人可以解释为什么初始化器不能肯定地为每个数字保留2个小数位吗?我真的很想像应该那样将价格存储在Core Data中。每次显示时格式化都不太方便。
UPDATE :
通过数据模型将Core Data对象转换为NSDecimalNumber类型,79.99和99.99不再是问题,但现在使用不同的数字更易于管理...
(30个答案)
4年前关闭。
出于某种原因,我的Swift应用程序中的某些Doubles在转换为NSNumber时给了我麻烦,而有些则没有。我的应用程序需要将具有2个小数位(价格)的 double 数转换为NSNumbers,以便可以使用Core Data进行存储和检索。例如,除非使用NSNumber的doubleValue方法进行特殊格式设置,否则某些特殊价格(例如79.99)将评估为99.98999999999999。
在这里,selectedWarranty.price = 79.99,如调试器中所示
// item.price: NSNumber?
// selectedWarranty.price: Double?
item.price = NSNumber(double: selectedWarranty.price!)
我编写了一些打印语句,以显示转换如何进行
Original double: 79.99
Converted to NSNumber: 79.98999999999999
.doubleValue Representation: 79.99
有人可以解释为什么初始化器不能肯定地为每个数字保留2个小数位吗?我真的很想像应该那样将价格存储在Core Data中。每次显示时格式化都不太方便。
UPDATE :
通过数据模型将Core Data对象转换为NSDecimalNumber类型,79.99和99.99不再是问题,但现在使用不同的数字更易于管理...
Original double: 39.99
Converted 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?
10-06 09:11