用BigDecimal計算金額就高枕無憂了?帶你了解BigDecimal這五個坑

BigDecimal是java.math包中提供的API類,專門用于對超過16位有效位的數進行精確的運算。一般情況下,對于不需要準確精度的計算,我們可以通過float或者double進行計算,但是如果需要精確計算的結果,就必須使用BigDecimal類來操作。
而BigDecamal本質上是一個對象,所以傳統的+、-、*、/等算術運算符就不能直接使用了。
今天我們來了解一下,使用BigDecimal時容易踩的五個坑。
1、錯誤的初始化

BigDecimal提供了很多初始化方法,但是需要注意的是,當我們使用double這種浮點型初始化,可能得到預期外的結果。

當我們使用浮點型進行初始化時,由于其本身就是一個不確定的值,傳給BigDecimal初始化時已經丟失了精度,所以看起來就像一個bug。
一般來說,建議大家初始化時將其轉為String或者使用BigDecimal.valueOf方法。

2、錯誤的等值比較方法

equal方法會比較兩個BigDecimal對象的精度,如果精度不同,則認為是兩個不同的對象。
如果要比較兩個對象的大小,建議使用compareTo方法。
3、未指定精度可能會導致異常

如果除法的商是一個無限小數,而我們又沒有指定精度大小,程序將拋出一個異常。當我們使用BigDecimal時,應該時刻記得指定精度,避免因為精度問題帶來的損失。
4、toString方法的格式問題
當我們想把一個BigDecimal.valueOf構造的BigDecimal轉為String時,應該了解到toString方法和toPlainString方法的區別。
toString:必要時會使用科學計數法。
toPlainString:不使用科學計數法。
toEngineeringString:工程計算中經常使用的記錄數字的方法,與科學計數法類似,但要求10的冪必須是3的倍數。
5、執行順序不同導致的結果差異

當執行算術運算時,會滿足乘法交換律,但是對于BigDecimal來說,是不適用的。
不同的執行順序會得到不同的結果,對于金融類的需求,這0.1的差額,足夠你排除bug到半夜了。
總結
1、BigDecimal雖然計算精度準確,但是其性能相對double,float是較差的。如果沒有高精度計算的要求,那也不必強行使用BigDecimal。
2、初始BigDecimal時,建議強制使用字符串的構造參數。
3、BigDecimal對象是不可變的,每次計算都會產生一個新對象,所以記得保存做完計算以后的值。

























