1
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

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

4

2 回答 2

4

Double 类的 parseDouble 添加额外的零

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.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;
}

这假定小数点后两位。

于 2013-02-02T10:50:28.333 回答
0

Double 类的 parseDouble 添加额外的零

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

于 2013-02-02T23:32:27.313 回答