1. 程式人生 > >轉--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">
一、BigDecimal介紹

      Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中若需要精確的計算結果則要用java.math.BigDecimal類。

二、BigDecimal用法

BigDecimal所建立的是物件,故我們不能使用傳統的+、-、*、/等算術運算子直接對其物件進行數學運算,而必須呼叫其相對應的方法。方法中的引數也必須是BigDecimal的物件。構造器是類的特殊方法,專門用來建立物件,特別是帶有引數的物件。

  • 下面介紹BigDecimal的構造方法
  1. BigDecimal(int)           建立一個具有引數所指定整數值的物件。
  2. BigDecimal(double)   建立一個具有引數所指定雙精度值的物件。
  3. BigDecimal(long)        建立一個具有引數所指定長整數值的物件。
  4. BigDecimal(String)    建立一個具有引數所指定以字串表示的數值的物件。
1 2 BigDecimal a = new BigDecimal ( "1.22" ) ; System . out . println ( "a values is:" + a ) ;
通過上面的步驟我們利用String構造的方式建立了一個BigDecimal例項化物件a,這時請問上面的輸出是多少?

很多人可能覺得那輸出結果不就是1.22嘛,可實際結果呢?

正確輸出 :1.2199999999999999733546474089962430298328399658203125

既然是精確的大數類實現,它自然會有自己的特別之處,下來看看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構造方法。 
  3. 當double必須用作BigDecimal的源時,請注意,此構造方法提供了一個準確轉換;它不提供與以下操作相同的結果:先使用Double.toString(double)方法,然後使用BigDecimal(String)構造方法,將double轉換為String。要獲取該結果,請使用static valueOf(double)方法。
  • BigDecimal常用方法描述
  1. add(BigDecimal)            BigDecimal物件中的值相加,然後返回這個物件。
  2. subtract(BigDecimal)    BigDecimal物件中的值相減,然後返回這個物件。
  3. multiply(BigDecimal)    BigDecimal物件中的值相乘,然後返回這個物件。
  4. divide(BigDecimal)        BigDecimal物件中的值相除,然後返回這個物件。
  5. toString()                         將BigDecimal物件的數值轉換成字串。
  6. doubleValue()                 將BigDecimal物件中的值以雙精度數返回。
  7. floatValue()                     將BigDecimal物件中的值以單精度數返回。
  8. longValue()                     將BigDecimal物件中的值以長整數返回。
  9. 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的用法,下面再介紹常用的幾種對BigDecimal進行格式化的方法

        由於NumberFormat類的format()方法可以使用BigDecimal物件作為其引數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。

         以利用BigDecimal對貨幣和百分比格式化為例。首先,建立BigDecimal物件,進行BigDecimal的算術運算後,分別建立對貨幣和百分比格式化的引用,最後利用BigDecimal物件作為format()方法的引數,輸出其格式化的貨幣值和百分比。

[java] view plain copy print ?
  1. public static void main(String[] args) {  
  2.     NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立貨幣格式化引用   
  3.     NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用   
  4.     percent.setMaximumFractionDigits(3); //百分比小數點最多3位   
  5.       
  6.     BigDecimal loanAmount = new BigDecimal("15000.48"); //貸款金額  
  7.     BigDecimal interestRate = new BigDecimal("0.008"); //利率     
  8.     BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
  9.    
  10.     System.out.println("貸款金額:\t" + currency.format(loanAmount));   
  11.     System.out.println("利率:\t" + percent.format(interestRate));   
  12.     System.out.println("利息:\t" + currency.format(interest));   
  13. }  
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 ?
  1. publicstaticvoidmain(String[]args){  
  2.     BigDecimala=newBigDecimal("1");  
  3.     BigDecimalb=newBigDecimal("2");  
  4.     BigDecimalc=newBigDecimal("1");  
  5.     intresult1=a.compareTo(b);  
  6.     intresult2=a.compareTo(c);  
  7.     intresult3=b.compareTo(a);  
  8.     System.out.println(result1);  
  9.     System.out.println(result2);  
  10.     System.out.println(result3);  
  11.       
  12. }  
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

即左邊比右邊數大,返回1,相等返回0,比右邊小返回-1。注意 不可用equals進行相等的判斷,equals 比較是兩個BigDecimal物件的地址。 

五、BigDecimal總結

  1. 在需要精確的小數計算時再使用BigDecimal,BigDecimal的效能比double和float差,在處理龐大,複雜的運算時尤為明顯。故一般精度的計算沒必要使用BigDecimal。
  2. 儘量使用引數型別為String的建構函式。
  3.  BigDecimal都是不可變的(immutable)的, 在進行每一次四則運算時,都會產生一個新的物件 ,所以在做加減乘除運算時要記得要儲存操作後的值。