解析双精度类的双精度添加额外的零


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() BigDecimal

System.out.println(Double.parseDouble("0.006")); 
System.out.println(BigDecimal.valueOf(0.006).doubleValue());

为我返回 0.0060

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

解析双精度类的双精度添加额外的零

Java 1.4 到 6 中有一个错误 id:4428022,这意味着它增加了一个你不需要的额外零。 这仅适用于值 0.001 到 0.009。 Java 7没有这个错误。

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

在 Java 6 打印中

0.00100.00200.00300.00400.00500.00600.00700.00800.0090

但在 Java 7 打印中

0.0010.0020.0030.0040.0050.0060.0070.0080.009


我怀疑 0.65 实际上实际上略少。当你把它除以 100 时,你会得到类似 0.0064999999999999 的东西,当四舍五入时下降到 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;
}

这假设美分的小数点后两位。

解析双精度类的双精度添加额外的零

不,它没有。您用来格式化双精度的方法就是这样做的。双精度不包含尾随十进制零。它们不包含十进制的任何内容。

最新更新