Java BigDecimal使用及基本運算(推薦)
BigDecimal簡介
Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java.math.BigDecimal。BigDecimal所建立的是物件,我們不能使用傳統的+、-、*、/等算術運算子直接對其物件進行數學運算,而必須呼叫其相對應的方法。方法中的引數也必須是BigDecimal的物件。構造器是類的特殊方法,專門用來建立物件,特別是帶有引數的物件。
提起BigDecimal,相信大家都使用過,之所以總結這篇呢,是因為最近發現專案中使用的不是太規範,在某些場景下甚至出現程式碼丟擲異常的情況,
所以就總結了這篇,希望大家在使用時,可以少踩一些坑。
1. 基本運算
1.1 加法
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.add(number2); System.out.println("number1 add number2 = " + number3);
輸出結果:
number1 add number2 = 100.00
1.2 減法
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.subtract(number2); System.out.println("number1 subtract number2 = " + number3);
輸出結果:
number1 subtract number2 = 77.76
1.3 乘法
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.multiply(number2); System.out.println("number1 multiply number2 = " + number3);
輸出結果:
number1 multiply number2 = 988.3456
1.4 除法
BigDecimal number1 = new BigDecimal("88"); BigDecimal number2 = new BigDecimal("11"); BigDecimal number3 = number1.divide(number2); System.out.println("number1 divide number2 = " + number3);
輸出結果:
number1 divide number2 = 8
因為上面2個數可以整除,所以這麼用沒有問題,不過一但不能被整除,這麼用就會有潛在的風險,會丟擲java.lang.ArithmeticException
異常,所以強烈建議像下面這樣使用:
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.divide(number2,2,RoundingMode.HALF_UP); System.out.println("number1 divide number2 = " + number3);
輸出結果:
number1 divide number2 = 7.99
此時使用的divide()方法原始碼如下所示:
public BigDecimal divide(BigDecimal divisor,int scale,RoundingMode roundingMode) { return divide(divisor,scale,roundingMode.oldMode); }
這裡的scale指的是要保留的小數位數,我們傳的是2,即保留2位小數。
這裡的roundingMode指的是舍入模式,我們這裡傳的是RoundingMode.HALF_UP
,即經常使用的四捨五入模式。
1.5 保留小數位數
如果我們想對BigDecimal型別保留小數位數,可以使用setScale()方法,使用方法如下所示:
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.multiply(number2); System.out.println("number1 multiply number2 = " + number3); // 保留3位小數,四捨五入 BigDecimal number4 = number3.setScale(3,RoundingMode.HALF_UP); System.out.println("number3 setScale = " + number4);
輸出結果:
number1 multiply number2 = 988.3456
number3 setScale = 988.346
1.6 比較大小
BigDecimal比較大小,可以使用compareTo()方法,使用方法如下所示:
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = new BigDecimal("11.11"); BigDecimal number3 = new BigDecimal("99.99"); BigDecimal number4 = new BigDecimal("88.88"); System.out.println("number1 compareTo number2 = " + number1.compareTo(number2)); System.out.println("number1 compareTo number3 = " + number1.compareTo(number3)); System.out.println("number1 compareTo number4 = " + number1.compareTo(number4));
輸出結果:
number1 compareTo number2 = 1
number1 compareTo number3 = -1
number1 compareTo number4 = 0
由輸出結果可以看出:
當number1小於number2時,返回-1,
當number1等於number2時,返回0,
當number1大於number2時,返回1。
2. 踩坑總結
2.1 NullPointerException異常
在使用BigDecimal型別進行計算時,比如上面提到的加、減、乘、除、比較大小時,一定要保證參與計算的兩個值不能為空,否則會丟擲java.lang.NullPointerException
異常。
比如下面的2段程式碼,都會丟擲異常:
BigDecimal number1 = null; BigDecimal number2 = new BigDecimal("11.12"); BigDecimal number3 = number1.add(number2); System.out.println("number1 add number2 = " + number3);
BigDecimal number1 = new BigDecimal("88.88"); BigDecimal number2 = null; BigDecimal number3 = number1.add(number2); System.out.println("number1 add number2 = " + number3);
丟擲的異常如下圖所示:
2.2 ArithmeticException異常
一次在使用BigDecimal
的divide
方法時,丟擲java.lang.ArithmeticException
異常,錯誤程式碼如下所示:
// 含稅金額 BigDecimal inclusiveTaxAmount = new BigDecimal("1000"); // 稅率 BigDecimal taxRate = new BigDecimal("0.13"); // 不含稅金額 = 含稅金額 / (1+稅率) BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate)); System.out.println(exclusiveTaxAmount);
執行時丟擲以下異常:
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
報錯原因是因為無法整除,導致結果是無限迴圈小數:
解決方案是指定下舍入模式,比如我們最常用的四捨五入模式:
// 不含稅金額 = 含稅金額 / (1+稅率) BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate),RoundingMode.HALF_UP);
此時不再報錯,輸出結果為:
885
但這裡我的需求是保留2位小數,四捨五入,因此程式碼應該是下面這樣的:
// 不含稅金額 = 含稅金額 / (1+稅率) BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate),RoundingMode.HALF_UP);
此時的輸出結果為:
884.96
如果你的IDEA裝了阿里巴巴程式碼規範外掛,如果不指定RoundingMode
,會有下面這樣的提示:
3. 使用規範
儘量不要在專案中使用new BigDecimal("0")
,而是使用BigDecimal提供的常量BigDecimal.ZERO
。
BigDecimal zero = BigDecimal.ZERO; BigDecimal one = BigDecimal.ONE; BigDecimal ten = BigDecimal.TEN;
總結
到此這篇關於Java BigDecimal使用指南針(推薦)的文章就介紹到這了,更多相關Java BigDecimal使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!