複製鏈接
請複製以下鏈接發送給好友

BigDecimal

鎖定
Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java.math.BigDecimal。BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。 [1] 
外文名
BigDecimal
包    括
帶有參數的對象
提    供
API類BigDecimal
功    能
對超過16位有效位的數進行精確的運算
關    聯
float、double
應    用
商業計算

BigDecimal構造方法

BigDecimal一共有4個構造方法:
BigDecimal(int) 創建一個具有參數所指定整數值的對象。
BigDecimal(double) 創建一個具有參數所指定雙精度值的對象。(不建議採用)
BigDecimal(long) 創建一個具有參數所指定長整數值的對象。
BigDecimal(String) 創建一個具有參數所指定以字符串表示的數值的對象 [1] 
為什麼不建議採用第二種構造方法?如下代碼:
代碼1 代碼1
運行結果如圖所示:
運行結果 運行結果
原因:JDK的描述:1、參數類型為double的構造方法的結果有一定的不可預知性。有人可能認為在Java中寫入newBigDecimal(0.1)所創建的BigDecimal正好等於 0.1(非標度值 1,其標度為 1),但是它實際上等於0.1000000000000000055511151231257827021181583404541015625。這是因為0.1無法準確地表示為 double(或者説對於該情況,不能表示為任何有限長度的二進制小數)。這樣,傳入到構造方法的值不會正好等於 0.1(雖然表面上等於該值)。2、另一方面,String 構造方法是完全可預知的:寫入 newBigDecimal("0.1") 將創建一個 BigDecimal,它正好等於預期的 0.1。因此,比較而言,通常建議優先使用String構造方法 [2] 
當double必須用作BigDecimal的源時,請使用Double.toString(double)轉成String,然後使用String構造方法,或使用BigDecimal的靜態方法valueOf,如下:
代碼2 代碼2
運行結果:
運行結果 運行結果

BigDecimal格式化及例子

由於NumberFormat類的format()方法可以使用BigDecimal對象作為其參數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。 以利用BigDecimal對貨幣和百分比格式化為例。首先,創建BigDecimal對象,進行BigDecimal的算術運算後,分別建立對貨幣和百分比格式化的引用,最後利用BigDecimal對象作為format()方法的參數,輸出其格式化的貨幣值和百分比 [3] 
代碼樣例:
BigDecimal bigLoanAmount = new BigDecimal("具體數值");   //創建BigDecimal對象
BigDecimal 
bigInterestRate = new BigDecimal("具體數值");

BigDecimal bigInterest = bigLoanAmount.multiply(bigInterestRate);//BigDecimal運算
NumberFormat 
currency = NumberFormat.getCurrencyInstance();    //建立貨幣格式化引用

NumberFormat percent = NumberFormat.getPercentInstance();     //建立百分比格式化用

percent.setMaximumFractionDigits(3);               //百分比小數點最多3位

//利用BigDecimal對象作為參數在format()中調用貨幣和百分比格式化

System.out.println("Loan amount:\t" + currency.format(bigLoanAmount));

System.out.println("Interest rate:\t" + percent.format(bigInterestRate));

System.out.println("Interest:\t" + currency.format(bigInterest));

輸出結果:
Loan amount:  ¥129,876,534,219,876,523.12
Interest rate: 8.765%
Interest:  
¥11,384,239,549,149,661.69
常見用法:
初始化 BigDecimal a= new BigDecimal("1.35");

對數值取值:
1.a.setScale(1,BigDecimal.ROUND_DOWN);

取一位小數,直接刪除後面多餘位數,故取值1.3.
2.a.setScale(1,BigDecimal.ROUND_UP);

取一位小數,刪除後面位數,進一位,故取值1.4.
3.a.setScale(1,BigDecimal.ROUND_HALF_UP);

取一位小數,四捨五入,故取值1.4.
4.a.setScale(1,BigDecimal.ROUND_HALF_DOWN);

取一位小數,五舍六入,故取值1.3.




BigDecimalBigDecimal加減乘除運算

對於常用的加,減,乘,除,BigDecimal類提供了相應的成員方法 [2] 
public BigDecimal add(BigDecimal value); //加法
public BigDecimal subtract(BigDecimal value); //減法
public BigDecimal multiply(BigDecimal value); //乘法
public BigDecimal divide(BigDecimal value); //除法
用法如下:
代碼3 代碼3
運行結果:
運行結果 運行結果
需要注意的是除法運算divide.
BigDecimal除法可能出現不能整除的情況,比如 4.5/1.3,這時會報錯java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
其實divide方法有可以傳三個參數:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一參數表示除數, 第二個參數表示小數點後保留位數,第三個參數表示舍入模式,只有在作除法運算或四捨五入時才用到舍入模式,有下面這幾種 [2] 
舍入模式 舍入模式
參考資料
  • 1.    java.math.BigDecimal類的用法  .iteye.2010-04-24[引用日期2013-05-28]
  • 2.    Mathar R J. A Java Math.BigDecimal Implementation of Core Mathematical Functions[J]. 2012.
  • 3.    李文化. 基於大整數的BigDecimal類的實現[J]. 計算機光盤軟件與應用, 2010(6):120-122.