分享知識 傳遞快樂
Double 轉 BigDecima l并保留兩位小數出現異常: java.lang.ArithmeticException: Rounding necessary 。
代碼如下:
public static void main(String[] args) {
Double d1 = 0.10;
BigDecimal bigDecimal1 = new BigDecimal(d1).setScale(2);
System.out.println(bigDecimal1);
// 或
Double d2 = 0.123;
BigDecimal bigDecimal2 = new BigDecimal(d2).setScale(2);
System.out.println(bigDecimal2);
}
輸出結果:
java.lang.ArithmeticException: Rounding necessary
java.lang.ArithmeticException: Rounding necessary
異常分析:
使用 Double 轉 BigDecimal 并保留兩位小數出現異常: java.lang.ArithmeticException: Rounding necessary 的原因是:精度丢失。
setScale(int newScale) 方法内部調用 setScale(int newScale, int roundingMode) 方法,傳入預設舍入模式:ROUND_UNNECESSARY,在方法内部對精度處理時,如果存在精度丢失則抛出異常,如果不存在精度丢失則不會抛出異常。
解決方案
public static void main(String[] args) {
Double d = 0.10;
BigDecimal bigDecimal1 = new BigDecimal(d).setScale(2,BigDecimal.ROUND_FLOOR );
BigDecimal bigDecimal2 = new BigDecimal(d+"").setScale(2);
System.out.println(bigDecimal1);
System.out.println(bigDecimal2);
// 精度3位以上,結果保留兩位
d = 0.125;
BigDecimal bigDecimal2 = new BigDecimal(d + "").setScale(2,BigDecimal.ROUND_FLOOR);
System.out.println(bigDecimal2);
}
輸出結果
0.10
0.10
0.12
拓展
public final static int ROUND_DOWN:舍入模式向零舍入。 永遠不要在丢棄的分數之前增加數字(即截斷)。 請注意,此舍入模式永遠不會增加計算值的大小
public final static int ROUND_CEILING:舍入模式向正無窮大舍入。 如果BigDecimal為正數,則表現為ROUND_UP ; 如果為負,則表現為ROUND_DOWN 。 請注意,此舍入模式永遠不會減少計算值。
public final static int ROUND_FLOOR:舍入模式向負無窮大舍入。 如果BigDecimal為正數,則按照ROUND_DOWN進行ROUND_DOWN ; 如果為負,則按照ROUND_UP方式行事。 請注意,此舍入模式不會增加計算值
public final static int ROUND_HALF_DOWN:舍入模式向“最近鄰居”舍入,除非兩個鄰居等距,在這種情況下向下舍入。 如果丢棄的分數 > 0.5,則行為與ROUND_UP ; 否則,行為與ROUND_DOWN 。
public final static int ROUND_HALF_EVEN:舍入模式向“最近鄰居”舍入,除非兩個鄰居等距,在這種情況下,向偶數鄰居舍入。 如果丢棄的分數左邊的數字是奇數,則行為與ROUND_HALF_UP ; 如果為ROUND_HALF_DOWN則表現為ROUND_HALF_DOWN 。 請注意,這是在一系列計算中重複應用時最小化累積誤差的舍入模式。
public final static int ROUND_HALF_UP:舍入模式向“最近鄰居”舍入,除非兩個鄰居等距,在這種情況下向上舍入。 如果丢棄的分數 ≥ 0.5,則行為與ROUND_UP ; 否則,行為與ROUND_DOWN 。 請注意,這是我們大多數人在國小時所教的舍入模式。是常用的四舍五入方式
public final static int ROUND_UNNECESSARY:舍入模式斷言請求的操作具有精确結果,是以不需要舍入。 如果在産生不精确結果的操作上指定了此舍入模式,則會引發ArithmeticException 。
public final static int ROUND_UP:舍入模式從零舍入。 總是在非零丢棄分數之前增加數字。 請注意,此舍入模式永遠不會降低計算值的大小。。