解決java.math.BigDecimal divide方法運算結果為無限小數問題


http://samueli.iteye.com/blog/224755
BigDecimal除法運算報錯,錯誤如下:
Non-terminating decimal expansion; no exact representable decimal result

 

原因是:

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

if divisor is zero, roundingMode==ROUND_UNNECESSARY and the specified scale is insufficient to represent the result of the division exactly
所以使用divide時應該指定scale和roundingMode,保證對於無限小數有足夠的范圍來表示結果。

 
 
問題擴展:
10/3=3.3333333333333333.............. 
Java代碼   收藏代碼
  1. public static void main(String[] args) {  
  2.     BigDecimal a = new BigDecimal("10");  
  3.     BigDecimal o = new BigDecimal("3");  
  4.     System.out.print(a.divide(o).setScale(2, BigDecimal.ROUND_DOWN).doubleValue());  
  5. }  

Java代碼  
  1. Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.  
  2.     at java.math.BigDecimal.divide(BigDecimal.java:1514)  
  3.     at test.main(test.java:8)  

解決方法: 
Java代碼  
  1. public static void main(String[] args) {  
  2.     BigDecimal a = new BigDecimal("10");  
  3.     BigDecimal o = new BigDecimal("3");  
  4.     System.out.print(a.divide(o,2, BigDecimal.ROUND_DOWN).doubleValue());         
  5. }  

輸出:3.33 


需要注意的地方: 
Java代碼  
  1. /** 
  2. * (1)BigInteger和BigDecimal都是不可變(immutable)的,在進行每一步運算時,都會產生一個新的對象,由於創建對象會引起開銷, 
  3. * 它們不適合於大量的數學計算,應盡量用long,float,double等基本類型做科學計算或者工程計算。 
  4. * 設計BigInteger和BigDecimal的目的是用來精確地表示大整數和小數,使用於在商業計算中使用。 
  5. * (2)BigDecimal有4個夠造方法,其中的兩個用BigInteger構造,另一個是用double構造,還有一個使用String構造。 
  6. * 應該避免使用double構造BigDecimal,因為:有些數字用double根本無法精確表示,傳給BigDecimal構造方法時就已經不精確了。 
  7. * 比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。 
  8. * 使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精確計算,用String構造BigDecimal,避免用double構造,盡管它看起來更簡單! 
  9. * (3)equals()方法認為0.1和0.1是相等的,返回true,而認為0.10和0.1是不等的,結果返回false。 
  10. * 方法compareTo()則認為0.1與0.1相等,0.10與0.1也相等。所以在從數值上比較兩個BigDecimal值時,應該使用compareTo()而不是 equals()。 
  11. * (4)另外還有一些情形,任意精度的小數運算仍不能表示精確結果。例如,1除以9會產生無限循環的小數 .111111...。 
  12. * 出於這個原因,在進行除法運算時,BigDecimal可以讓您顯式地控制舍入。 
  13. */  
 
實戰:
比如:
//聲明d,無論哪一種聲明方式結果都是一樣的,數字超過8位就有問題,跟double長度有關
Double d = 22722222.0;
//Double d = Double.parseDouble("22722222.0");
//Double d = Double.valueOf("22722222.0");
//Double d = new Double("22722222.0");
//輸出d結果
System.out.println(d.toString());
結果:2.2722222E7
2.2722222E7!計算條件若是錯誤的,計算結果怎么都會錯啊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM