在Java中构造BigDecimal时,为什么Double.toString的行为与MathContext.DECIMAL64不一样?

时间:2013-10-17 16:01:58

标签: java double rounding bigdecimal floating-point-precision

对我而言,似乎Double应遵循与MathContext.DECIMAL64中使用的IEEE标准相同的规则,但是,在这种情况下,我会得到不同的行为:

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

1 个答案:

答案 0 :(得分:3)

BigDecimal任意精度带符号的十进制数。另一方面,double是浮点数,因此它意味着对所表示的数字有一些影响。

当您尝试从double创建Bigdecimal时,您将获得de double表示的值,在您的示例中为8.699999999999999。原因是双变量不能真正保持8.7。有关大小数的更多信息

http://goo.gl/tRMLhA

当您将数字表示为字符串时,“字符串方法”返回值为“8.7”​​的值,并且结果表示该值为Bigdecimal。方法toString使用一些rools来表示一个double值作为String看看

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

当你使用MathContext.DECIMAL64时,你说“好吧我知道双号上有一些不完美之处。我希望你能用16位数和圆形模式进行四舍五入”这就是你得到的。 Java采用8.7的双重表示形式,即8.6999999999999993,并将其四舍五入为16位数 8.699999999999999因为数字17是“3”,因此四舍五入的结果是数字16,因为它是9。

有关MathContext.DECIMAL64含义的信息: http://goo.gl/fVUehh

如果你想获得8.7,只需使用低于16位的精确度。

示例代码

/**
     * @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

有关BigDecimal的更多信息和

上的双打

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