今天在用到 BigDecimal 做除法時候遇到這樣一個錯
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result
後面一查,發現是對 BigDecimal 不熟悉,用錯方法的緣故。BigDecimal 類型用 divide(BigDecimal divisor) 方法做除法的時候,如果除不盡,就會報上面的這個錯。正確的操作應該是用它的重載方法 divide(BigDecimal divisor, int scale, int roundingMode) 。
需注意的是這個方法有三個參數,(第一個是 除數,第二個是結果保留的精度,第三個是舍位模式),
同時它有個兩個參數的重載方法divide(BigDecimal divisor,int roundingMode)(第一個是 除數,第二個是舍位模式)。兩個參數的方法默認保留精度是0,保留整數。(兩個參數的方法不要把第二個參數當成結果保留的精度)。
再說一下舍位模式:(以保留兩位舉例)
名稱 | 對應值 | 解釋說明 | 舉例 |
---|---|---|---|
ROUND_UP |
0 |
朝遠離數軸原點的方向進位 |
3.3333 —> 3.34; 22.1234 —> -22.13; |
ROUND_DOWN |
1 |
朝靠近數軸原點的方向進位 |
3.3333 —> 3.33; -22.1234 —> -22.12; |
ROUND_CEILING |
2 |
按保留位數取大於等於它的最小數 |
3.3333 —> 3.34; -22.1234 —> -22.12; |
ROUND_FLOOR |
3 |
按保留位數四捨五入 負數先取絕對值再四捨五入 |
3.3333 —> 3.33; -22.1234 —> -22.13; |
ROUND_HALF_UP |
4 |
按保留位數四捨五入 負數先取絕對值再四捨五入 |
3.3333 —> 3.33; -22.1234 —> -22.13; 2.345 —> 2.35; |
ROUND_HALF_DOWN |
5 |
按保留位數四捨六入,五看情況,五後非空進 一位,五後爲空(或全0)捨去,負數先取絕對值 再按規則保留 |
1.13501 —> 1.14; 1.135 —> 1.13; -2.345 —> -2.34; -2.3456 —> -2.35; |
ROUND_HALF_EVEN |
6 |
這個叫"銀行家舍入",按保留位數四捨六入, 五看情況,五後非空進一位,五後爲空(或全0) 看(五前面一位的)奇偶,五前爲偶應捨去, 五前爲奇要進一,負數先取絕對值再按規則保留 |
五後非空: 1.12501 —> 1.13;
五後爲空,五前爲偶: 1.12500000—> 1.13 |
ROUND_UNNECESSARY |
7 |
斷言請求的操作具有精確的結果,因此不需要舍入。 如果對獲得精確結果的操作指定此舍入模式,則拋 出 arithmeticexception |
1.1000 —> 1.10; 2.3333... —> 拋出算術異常; |