我已将CoreData对象 LineItem 中的价格定义为 double ,但要设置或使用的值价格,我只能使用 NSNumber 包装器,这就是CoreData的工作原理,它很好。
但是我在设置数字时发现了准确性问题。
例如,我从UITextField数字输入中获得了一个双精度:
[self.lineItem setPriceValue:round([_finalPrice doubleValue]*100)/100]; // This actually trivial since it is already 83.99 as you see in the log but doesn't affect the result.
NSLog(@"Price to set: %@", _finalPrice);
NSLog(@"Price set: %@", [self.lineItem price]);
这是日志:
2014-03-30 21:03:24.207 MyApp[20998:60b] Price to set: 83.99
2014-03-30 21:03:24.207 MyApp[20998:60b] Price set: 83.98999999999999
这看起来像是十字小故障之一,除了我没有在任何地方真正使用过十进制的事实。 RestKit有可能在某处使用它,这是我无法控制的,但我对此表示怀疑。
同时它在我的应用程序中引起问题,因为它是一个商业应用程序,我与之交谈的API只读取83.98999999999999为83.98,在涉及这些有问题的数字的每笔交易中造成一两次折扣。
答案 0 :(得分:5)
浮点类型float
和double
以二进制形式存储数字,而不是所有小数部分都具有等效的精确二进制分数。因此,需要精确的货币计算应该使用整数类型,使用适当的单位,例如美分或便士,或者使用十进制浮点类型,例如由NSDecimalNumber
提供。选择使用取决于您需要表示的值的范围以及您需要执行的计算类型。