double类的parseDouble增加了额外的零

时间:2013-02-02 10:45:22

标签: java rounding

public static double centsToDollars(Number cents, int precision) {
    return BigDecimal.valueOf(cents.doubleValue() / 100).setScale(precision, RoundingMode.DOWN).doubleValue();
}

当我想以美元显示分值时,上面的代码完全正常。例如,1美分,它返回0.01美元。

assertEquals("$0.01", FormatUtils.centsToDollars(1, 3)) 
assertEquals("$0.012", FormatUtils.centsToDollars(1.2345, 3))
assertEquals("$0.327", FormatUtils.centsToDollars(32.7, 3))

但我无法弄清楚,为什么FormatUtils.centsToDollars(0.65, 3)会返回$ 0.0060。我希望收到0.006。什么是最新的零?

更新

看起来问题的根本原因是调用doubleValue()的{​​{1}}

BigDecimal

为我返回0.0060

为什么会发生这种情况的任何线索?

2 个答案:

答案 0 :(得分:4)

  

Double类的parseDouble增加了额外的零

Java 1.4到6中有一个bug id:4428022,这意味着它增加了一个你不需要的零。仅在值0.001到0.009时发生这种情况。 Java 7没有这个bug。

for (int i = 1; i <= 9; i++)
    System.out.println(i / 1000.0);
Java 6中的

打印

0.0010 0.0020 0.0030 0.0040 0.0050 0.0060 0.0070 0.0080 0.0090

但在Java 7中打印

0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009


我怀疑实际上0.65实际上略少。当你将它除以100时,你会得到类似于0.006499999999999的东西,当圆形下降到0.006

我怀疑你想要的是什么

public static String centsToDollars(Number cents, int precision) {
    return "$" + BigDecimal.valueOf(cents.doubleValue())
           .divide(BigDecimal.valueOf(100))
           .setScale(precision, RoundingMode.HALF_UP);
}

尝试

System.out.println(new BigDecimal(0.65 / 100));

这就是我写它的方式

public static String centsToDollars(double cents) {
    double rounded = Math.round(cents * 100) / 1e4;
    return "$" + rounded;
}

这假设两位小数。

答案 1 :(得分:0)

  

Double类的parseDouble增加了额外的零

不,不。您用来格式化 double的方法就是这样做的。双打不包含尾随小数零。它们不包含小数。