2013-10-17 54 views
3

對我來說,這似乎是雙重應該遵循相同的規則,在MathContext.DECIMAL64採用的IEEE標準,然而,在這種情況下,我得到不同的行爲:在Java中構造BigDecimal時,爲什麼Double.toString的行爲與MathContext.DECIMAL64不同?

import java.math.BigDecimal; 
import java.math.MathContext; 

public class BigDecimalTest { 

    public static void main(String[] args) { 

     double foo = 8.7; 

     System.out.println(new BigDecimal(foo, MathContext.DECIMAL64)); 
     System.out.println(new BigDecimal(Double.toString(foo))); 

    } 
} 

輸出:

8.699999999999999 
8.7 
+0

雙打你看了'Double.toString'的Javadoc中?它遵循不同的規範。 (由於向後兼容的原因,它確實無法改變。) –

回答

3

A BigDecimal任意精度帶符號的十進制數字。另一方面,double是一個浮點數,因此它意味着對所表示的數字有一些印象。

當您嘗試從你的德雙,在您的例子是8.699999999999999表示的值雙創建一個BigDecimal。原因是雙變量不能確切地保持8.7。關於大小數更多信息上

http://goo.gl/tRMLhA

當你所代表的數字作爲一個字符串「8.7」​​值由字符串方法返回和consecuentlly那asigned到的BigDecimal值。 toString方法使用一些rools表示double值當你使用你說:「好,我知道有雙數這樣一些缺陷MathContext.DECIMAL64一個字符串去看一下

http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#toString(double)&bwsCriterion=toString&bwsMatch=3

。我希望你用16位數字和圓形模式的一半進行舍入「這就是你得到的。 java的取8.7即8.6999999999999993雙表示法和輪它到16位的結果是 8.699999999999999原因位數17是一個「3」,因此舍入半起來的結果爲假位數16,因爲它是這是一個9.

信息關於MathContext.DECIMAL64上的含義: http://goo.gl/fVUehh

如果你想獲得8.7只使用大於16位的一個precission低。

示例代碼

/** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

      double foo = 8.7; 

      System.out.println(new BigDecimal(foo, MathContext.DECIMAL64)); 
      System.out.println(new BigDecimal(foo, new MathContext(16))); 
      System.out.println(new BigDecimal(foo, new MathContext(17))); 

      System.out.println(new BigDecimal(foo, new MathContext(1))); 
      System.out.println(new BigDecimal(foo, new MathContext(2))); 
      System.out.println(new BigDecimal(foo, new MathContext(3))); 
      System.out.println(new BigDecimal(foo, new MathContext(15))); 

      System.out.println(new BigDecimal(Double.toString(foo))); 

    } 

輸出

8.699999999999999 
8.699999999999999 
8.6999999999999993 
9 
8.7 
8.70 
8.70000000000000 
8.7 

更多信息aboutBigDecimal和

https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

+0

我也發現了這個問題 - 詳細介紹了Double.toString的工作方式。 http://stackoverflow.com/questions/7153979/algorithm-to-convert-an-ieee-754-double-to-a-string – dave

相關問題