float 和 double 主要是被設計用作科學及工程運算,若是需要精確結果的商業計算,它們並不適合,原因在於它們不能準確地表達 0.1 或任何 10⁻¹ 的倍數。
假設你口袋有 $1.03,而你花了 42¢,那會剩下多少?
不幸地,它的輸出結果是 0.6100000000000001,這不是唯一的特殊案例;假設你口袋有 $1,你買了 9 個 10¢ 的物品,那會找回多少零錢?
根據這個結果,你會拿回 $0.09999999999999998。
我們可能會覺得只要利用輸出前幾位數做四捨五入來 work around 就可以了,但這招並不是每次都能奏效。再來舉一個例子,假設現在你口袋有 $1,架上擺著糖果,價格依序為 10¢、20¢、30¢,依此類推,如果從第一顆糖果開始買起,你可以買多少顆糖果,並且能找回多少零錢?
當你跑完這段程式碼,你會發現你可以買 3 顆糖果,然後找回 $0.3999999999999999,這結果當然是錯的。要解決這個情況,我們必須改用 BigDecimal 來處理商業計算。
這次我們得到了正確的答案,你可以買 4 顆糖果,找回 $0.00。
不過,使用 BigDecimal 也有缺點,它寫起來不是很方便,而且格式也麻煩,不容易 review。另外一個方法就是視情況使用 int 或 long 來代換,像是在這個例子中,因為數值不大,我們可以把單位都改用分來計算。
Reference:
http://stackoverflow.com/questions/5257166
《Effective Java》Item 48