简体   繁体   English

为什么 java.math.BigDecimal.valueOf(double) 确实使用 new BigDecimal(String),而不是 new BigDecimal(double)

[英]why java.math.BigDecimal.valueOf(double) does use new BigDecimal(String), instead of new BigDecimal(double)

Here is the code:这是代码:

    public static void main(String[] args) {
    final double d1 = 811.440000;
    final double d2 = 425.530000;
    final double d3 = 384.270000;

    for (double d : Arrays.asList(d1, d2, d3)) {
        final String dstr = String.format("%f", d);
        BigDecimal bg1 =  BigDecimal.valueOf(d).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal bg2 = (new BigDecimal(dstr)).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal bg3 =    (new BigDecimal(d)).setScale(2, BigDecimal.ROUND_DOWN);
        System.out.printf("[%s : %f] {%f, %f} %f\n", dstr, d,     bg1, bg2,   bg3);
    }
}

Here is the output:这是输出:

[811.440000 : 811.440000] {811.440000, 811.440000} 811.440000
[425.530000 : 425.530000] {425.530000, 425.530000} 425.520000
[384.270000 : 384.270000] {384.270000, 384.270000} 384.260000

Why don't we change valueOf(double) method or the BigDecimal(double) constructor of the BigDecimal class so as to get a consistent result?我们为什么不改变 BigDecimal 类的 valueOf(double) 方法或 BigDecimal(double) 构造函数以获得一致的结果?

The problem here isn't that one of new BigDecimal(double) nor new BigDecimal(String) working false.这里的问题不是new BigDecimal(double)new BigDecimal(String)工作错误之一。

The problem here is, that double are not precise.这里的问题是,那个double并不精确。 They store their bits in a way, which can't represent all numbers.它们以一种不能代表所有数字的方式存储它们的位。

Here are some links about that topic:以下是有关该主题的一些链接:

slightly change the code:稍微修改一下代码:

    public static void main(String[] args) {
    final double d1 = (new Double("811.44")).doubleValue();
    final double d2 = (new Double("425.53")).doubleValue();
    final double d3 = (new Double("384.27")).doubleValue();
    final double DD = (new Double("999999999999999.95")).doubleValue();  // 15 9s before decimal point

    for (double d : Arrays.asList(d1, d2, d3)) {
        final String dstr = String.valueOf(d);
        BigDecimal bg1 =  BigDecimal.valueOf(d);
        BigDecimal bg2 = (new BigDecimal(dstr));
        BigDecimal bg3 =    (new BigDecimal(d));
        System.out.printf("* [%s : %s : %.15f] {%.15f, %.15f, %.15f}\n", dstr, d, d, bg1, bg2, bg3);
        System.out.printf("  [%s : %s : %.15f] {%.15f, %.15f, %.15f}\n", dstr, d, d, bg1.doubleValue(), bg2.doubleValue(), bg3.doubleValue());
    }
}

And this is the result:这是结果:

1000000000000000.000000000000000
x [811.44 : 811.44 : 811.440000000000000] {811.440000000000000, 811.440000000000000, 811.440000000000055}
  [811.44 : 811.44 : 811.440000000000000] {811.440000000000000, 811.440000000000000, 811.440000000000000}
x [425.53 : 425.53 : 425.530000000000000] {425.530000000000000, 425.530000000000000, 425.529999999999973}
  [425.53 : 425.53 : 425.530000000000000] {425.530000000000000, 425.530000000000000, 425.530000000000000}
x [384.27 : 384.27 : 384.270000000000000] {384.270000000000000, 384.270000000000000, 384.269999999999982}
  [384.27 : 384.27 : 384.270000000000000] {384.270000000000000, 384.270000000000000, 384.270000000000000}

From the output, it seems the lose of precision is introduced by the BigDecimal(double) constructor.从输出来看,似乎 BigDecimal(double) 构造函数引入了精度损失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM