轉--BigDecimal用法詳解
一、BigDecimal介紹</div> </div> </div> <article> <div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post"> <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/htmledit_views-0a60691e80.css"> <div class="htmledit_views">
Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中若需要精確的計算結果則要用java.math.BigDecimal類。
二、BigDecimal用法BigDecimal所建立的是物件,故我們不能使用傳統的+、-、*、/等算術運算子直接對其物件進行數學運算,而必須呼叫其相對應的方法。方法中的引數也必須是BigDecimal的物件。構造器是類的特殊方法,專門用來建立物件,特別是帶有引數的物件。
- 下面介紹BigDecimal的構造方法
- BigDecimal(int) 建立一個具有引數所指定整數值的物件。
- BigDecimal(double) 建立一個具有引數所指定雙精度值的物件。
- BigDecimal(long) 建立一個具有引數所指定長整數值的物件。
- BigDecimal(String) 建立一個具有引數所指定以字串表示的數值的物件。
1 2 | BigDecimal a = new BigDecimal ( "1.22" ) ; System . out . println ( "a values is:" + a ) ; |
很多人可能覺得那輸出結果不就是1.22嘛,可實際結果呢?
正確輸出 :1.2199999999999999733546474089962430298328399658203125既然是精確的大數類實現,它自然會有自己的特別之處,下來看看JDK的解釋:
- 引數型別為double的構造方法的結果有一定的不可預知性。有人可能認為在Java中寫入newBigDecimal(0.1)所建立的BigDecimal正好等於 0.1(非標度值 1,其標度為 1),但是它實際上等於0.1000000000000000055511151231257827021181583404541015625。這是因為0.1無法準確地表示為 double(或者說對於該情況,不能表示為任何有限長度的二進位制小數)。這樣,傳入到構造方法的值不會正好等於 0.1(雖然表面上等於該值)。
- 另一方面,String 構造方法是完全可預知的:寫入 newBigDecimal(“0.1”) 將建立一個 BigDecimal,它正好等於預期的 0.1。因此,比較而言, 通常建議優先使用String構造方法。
- 當double必須用作BigDecimal的源時,請注意,此構造方法提供了一個準確轉換;它不提供與以下操作相同的結果:先使用Double.toString(double)方法,然後使用BigDecimal(String)構造方法,將double轉換為String。要獲取該結果,請使用static valueOf(double)方法。
- BigDecimal常用方法描述
- add(BigDecimal) BigDecimal物件中的值相加,然後返回這個物件。
- subtract(BigDecimal) BigDecimal物件中的值相減,然後返回這個物件。
- multiply(BigDecimal) BigDecimal物件中的值相乘,然後返回這個物件。
- divide(BigDecimal) BigDecimal物件中的值相除,然後返回這個物件。
- toString() 將BigDecimal物件的數值轉換成字串。
- doubleValue() 將BigDecimal物件中的值以雙精度數返回。
- floatValue() 將BigDecimal物件中的值以單精度數返回。
- longValue() 將BigDecimal物件中的值以長整數返回。
- intValue() 將BigDecimal物件中的值以整數返回。
- 示例用法:
1 2 3 4 | BigDecimal a = new BigDecimal ( "1.11" ) ; BigDecimal b = new BigDecimal ( "2.22" ) ; a . add ( b ) ; System . out . println ( " a + b = " + a ) ; |
上面講解了BigDecimal的用法,下面再介紹常用的幾種對BigDecimal進行格式化的方法
由於NumberFormat類的format()方法可以使用BigDecimal物件作為其引數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。
以利用BigDecimal對貨幣和百分比格式化為例。首先,建立BigDecimal物件,進行BigDecimal的算術運算後,分別建立對貨幣和百分比格式化的引用,最後利用BigDecimal物件作為format()方法的引數,輸出其格式化的貨幣值和百分比。
[java] view plain copy print ?
- public static void main(String[] args) {
- NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立貨幣格式化引用
- NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用
- percent.setMaximumFractionDigits(3); //百分比小數點最多3位
- BigDecimal loanAmount = new BigDecimal("15000.48"); //貸款金額
- BigDecimal interestRate = new BigDecimal("0.008"); //利率
- BigDecimal interest = loanAmount.multiply(interestRate); //相乘
- System.out.println("貸款金額:\t" + currency.format(loanAmount));
- System.out.println("利率:\t" + percent.format(interestRate));
- System.out.println("利息:\t" + currency.format(interest));
- }
public static void main(String[] args) { NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立貨幣格式化引用 NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用 percent.setMaximumFractionDigits(3); //百分比小數點最多3位
BigDecimal loanAmount = new BigDecimal("15000.48"); //貸款金額 BigDecimal interestRate = new BigDecimal("0.008"); //利率 BigDecimal interest = loanAmount.multiply(interestRate); //相乘 System.out.println("貸款金額:\t" + currency.format(loanAmount)); System.out.println("利率:\t" + percent.format(interestRate)); System.out.println("利息:\t" + currency.format(interest));
}
執行結果 貸款金額: ¥15,000.48 利率: 0.8% 利息: ¥120.00 四、BigDecimal比較
下面介紹如何對BigDecimal進行比較大小
[java] view plain copy print ?
- publicstaticvoidmain(String[]args){
- BigDecimala=newBigDecimal("1");
- BigDecimalb=newBigDecimal("2");
- BigDecimalc=newBigDecimal("1");
- intresult1=a.compareTo(b);
- intresult2=a.compareTo(c);
- intresult3=b.compareTo(a);
- System.out.println(result1);
- System.out.println(result2);
- System.out.println(result3);
- }
publicstaticvoidmain(String[]args){
BigDecimala=newBigDecimal("1");
BigDecimalb=newBigDecimal("2");
BigDecimalc=newBigDecimal("1");
intresult1=a.compareTo(b);
intresult2=a.compareTo(c);
intresult3=b.compareTo(a);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
即左邊比右邊數大,返回1,相等返回0,比右邊小返回-1。注意 不可用equals進行相等的判斷,equals 比較是兩個BigDecimal物件的地址。
五、BigDecimal總結
- 在需要精確的小數計算時再使用BigDecimal,BigDecimal的效能比double和float差,在處理龐大,複雜的運算時尤為明顯。故一般精度的計算沒必要使用BigDecimal。
- 儘量使用引數型別為String的建構函式。
- BigDecimal都是不可變的(immutable)的, 在進行每一次四則運算時,都會產生一個新的物件 ,所以在做加減乘除運算時要記得要儲存操作後的值。