意外的結果
回答
舍入誤差。如果你看一下你的計算不投的結果,您可以:
1998.9999999999998
所以,當你投爲int,小數部分被丟棄,而不是圍捕,你會得到1998
的道德是,如果你需要一個確切的答案,根本不使用float/double。如果你談論的是像金錢這樣的離散值,那麼使用int並處理原子單位(例如便士)。如果你確實需要精確的小數,那麼BigDecimal
是你的朋友。
雖然您可以使用Math.round()
將結果帶到預期的位置,但這並不適用於所有情況,也無法解決潛在的問題。
這是因爲19.99不能完全表示。
System.out.println(new BigDecimal(19.99));
打印出這個實際代表的值,它最接近它可以表示的19.99。
19.989999999999998436805981327779591083526611328125
和19.99 * 100
是
System.out.println(new BigDecimal(19.99 * 100));
這是
1998.999999999999772626324556767940521240234375
的問題是,你有一個代表性的錯誤在19.99這是仍然存在的時候乘以100,你會得到一個號碼這太小了。
如果您通過100和回合下來這就是(int)
不應該期望獲得1998年
另一種方法是
System.out.println(Math.round(19.99 * 100));
雖然這是真的,但這個原因並不能解釋1998年的迴歸,19.99 * 100是1999. – 2012-08-06 11:51:40
我認爲這個回答解決了這個問題的*基礎*。 +1 – 2012-08-06 11:53:52
@SeanKenny我不關注。 '1998.9999999999998436805981327779591083526611328125'向下取整是'1998'? – 2012-08-06 11:54:48
因爲19.99 * 100的計算將產生多1998.999999,你將它轉換爲int將丟棄它的小數部分。
這是由於四捨五入的問題。 double
和float
很容易出現這些問題,這就是爲什麼建議您使用BigDecimal
類。
此代碼應打印的期望是什麼:
BigDecimal bg = new BigDecimal("19.99");
System.out.println(bg.multiply(new BigDecimal("10")));
這產生了:
199.90
System.out.println((19.99 * 100));
產生的結果爲1998年。9999999999998加入int鑄造它截斷小數部分並返回1998
浮點數據類型(float和double在Java中)只能近似表示大多數小數值。有關更多詳情,請參閱Joshua Bloch's關於此主題的智慧詞彙。
- 1. 意外結果
- 2. 意外結果
- 3. 意外的結果
- 4. 意外的結果
- 5. 意外的結果
- 6. 意外的結果
- 7. 意外的結果
- 8. 意外的結果
- 9. 意外的結果
- 10. 意外的結果
- 11. 意外的結果
- 12. 意外的結果排序
- 13. 意外的JSTL EL結果
- 14. 雙foreach意外的結果
- 15. timediff的意外結果
- 16. 意外的結果一起
- 17. 意外的結果PHP FMOD
- 18. 意外的結果C++
- 19. 「stringWithFormat:」的意外結果:
- 20. PDO :: FETCH_CLASSTYPE - 意外的結果
- 21. mef中意外的結果
- 22. Solr-Highlight:意外的結果
- 23. 意外的高樓結果
- 24. 意外的布爾結果
- 25. 意外的計算結果
- 26. Node.js bluebird.map意外的結果
- 27. Javascript意外的結果
- 28. 意外的結果與
- 29. 意外的結果mysql_fetch_array
- 30. xsltproc意外的結果 - libXML
我不認爲這解決了真正的問題,這是無法準確地表示19.99 – 2012-08-06 11:54:42
@BrianAgnew我已經添加了一點現在來解決這個問題。 – berry120 2012-08-06 11:56:43