1 回答

TA貢獻1775條經驗 獲得超8個贊
電腦不是魔法。它們不能以無限精度表示數字,因為這需要不存在的無限內存。他們使用一種創造性的解決方案來嘗試以一種涵蓋您想要表示的大多數數字的方式來表示浮點數,同時它仍然適合 32 位(浮點數)或 64 位(雙精度數)。但這確實意味著它不準確。雙精度/浮點數實際上只能表示有限數量的特定數字,如果您試圖讓一個數字表示不是其中之一的數字,則會得到它可以表示的最接近它的數字。
那么,哪些數字可以表示,哪些不可以表示?這非常棘手,因為計算機以 2 為基數工作,而我們人類傾向于以 10 為基數進行思考。
這導致了兩個重要的教訓:
每當您“渲染”雙精度或浮點數時,即向用戶顯示或出于任何其他原因將其轉換為字符串時,您必須向計算機指定您要查找的內容。“只是打印它”不會做,如果你嘗試這樣做(例如,
System.out.println(someDouble);
計算機只是猜測,通常會猜錯。這是正確的方法:System.out.printf("%.2f\n", someDouble)
或者如果你不想打印但轉換為字符串,String.format("%.2f", someDouble)
:您告訴 java 打印/字符串化它,以便在逗號后最多獲得 2 位數字。如果 2.7 表示為 2.6999999999999999852,它仍會打印 2.7,因為這是最接近的不超過 2 位數字-after-the-comma 字符串表示為 2.6999999999999999852。如果您希望保證精度(通常在處理金錢時是個好主意?。。?,根本不要使用 double 或 float。通常的解決方案是使用
int
或long
存儲美分而不是歐元或美元。有些人會建議你BigDecimal
改用,但我建議不要這樣做,除非你真的知道你需要它。分錢很棘手,需要自定義策略,甚至BigDecimal
不能在不四舍五入或崩潰的情況下將 4 美分分到 3 個銀行賬戶。BigDecimal
當你必須乘以細節時,這是一個更合理的想法,這會帶來很多外匯。在您的情況下,您需要應用增值稅計算,不要理會它并堅持使用美分,存儲在整數或多頭中。
使用float
而不是時得到不同結果的原因double
是浮點數僅占用 32 位內存,因此float
與double
. Java 的 System.out.println 將應用一些四舍五入(但不多)。這種四舍五入往往不足以隱藏float
.
18.78998464050293
是與 的實際答案完全一致的最接近的數字18.789984000000004
。
添加回答
舉報