2014-03-31 82 views
2

我在CoreData對象的LineItem定義價格是CoreData(使用RestKit)設置當,但是,設置或使用價格的價值,我只能使用NSNumber包裝,這是CoreData的工作方式,它就好。雙NSNumber的不準確的

但我在設置數字時發現了準確性問題。

例如,我有一個雙從一個的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

這與RestKit無關,它純粹是關於'double' /'NSNumber' /'description'。爲什麼你必須把它作爲一個數字來存儲?和你使用的API應該處理它就好 - 如果它不是那麼它應該被改變... – Wain

回答

5

浮點類型floatdouble以二進制形式存儲數字,而不是所有小數具有精確的二進制分數等效值。出於這個原因,貨幣計算需要精確,應該使用整數類型使用適當單位(例如美分或便士)或使用十進制浮點類型(例如由NSDecimalNumber提供)來完成。要使用的選擇取決於您需要表示的值的範圍以及需要執行的計算類型。

+0

謝謝!我已經把Double變成了Decimal,並開始使用NSDecimalNumber。有效。 – Sullivan

+0

感謝您的詳細解釋,我遇到了同樣的問題,並且非常瞭解這裏的正確解決方案。 – JocelynH