天天看點

Java-BigDecimal踩坑記錄

1.為什麼要用bigdecimal?

浮點數的計算過程中必然會造成精度丢失,bigdecimal丢失程度比float和double小。

float和double是基本資料類型,而bigdecimal是封裝類型。

有得必有失,bigdecimal耗費時間和空間換取精度準确。

2.初始化就存在精度問題

顯然,建議用bigdecimal.valueof()方法初始化

3.使用除法divide的時候需要設定取整方式

4.遇到過這樣一個例子,九折商品

商品定價從别的系統擷取,精确到兩位小數

折扣價 = 定價 * 0.9

隻有一個price字段用來存儲價格,java中使用bigdecimal,mysql中使用decimal(10,2)存儲。

存的時候存折扣價,使用的時候需要折扣價和定價。

使用折扣價的時候直接用price,使用定價的時候用折扣價去除以0.9。

這樣設計肯定是不合理的,這裡看一下會造成什麼問題。

當商品定價為13.99的時候。(現在商品價格到兩位小數也很正常)

這就導緻了13.98和13.99的精度差的問題,涉及到錢都無小事,目前想到有3種解決方案

(1)再開一列存價格,各玩各的

(2)隻存定價,折扣價的使用再去乘

(3)隻存折扣價,但是資料庫精度取小數點後4位,計算折扣的時候精度不會丢失,除回來也不會丢失

5.處理精度的參數roundingmode roundingmode

roundingmode就是個枚舉,bigdecimal.xxx,本質是數字0-7,代表精度處理方式

0和2,1和3沒有試出差别......

6.結論

能不用除法就不用除法