Java BigDecimal舍入错误

reg*_*sxp 1 java android rounding bigdecimal

我有以下函数用于舍入Java中的double值:

public static double round(double d, int decimalPlace) {

    BigDecimal bd = new BigDecimal(Double.toString(d));
    bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
    return bd.doubleValue();
}
Run Code Online (Sandbox Code Playgroud)

作为输入,此函数正在接收以下值:

double d = 7.3149999999999995;
int decimalPlace = 2
Run Code Online (Sandbox Code Playgroud)

但是,当函数返回时,返回的值是7.31,而不是7.32.我搜索了文档,看看为什么bd.SetScale与这种行为有关,但没有成功.

有没有人能解释为什么会这样?非常感谢!!

Jon*_*eet 11

有没有人能解释为什么会这样?

它遵守记录的行为:)来自文档:

如果通过操作减小比例,则必须将未缩放的值除以(而不是相乘),并且可以改变该值; 在这种情况下,指定的舍入模式应用于除法.

并为RoundingMode.HALF_UP:

舍入模式向"最近邻居"舍入,除非两个邻居等距,在这种情况下向上舍入.

现在7.3149999999999995 与7.31和7.32 都不等距 - 它更接近7.31,所以这就是结果.

只有当原始值恰好是7.315时才会看到HALF_UP和之间的区别HALF_DOWN,即两者之间的差异.

顺便说一句,以确保您得到准确,你希望入手的数量,我建议使用String.例如:

double d = 0.1;
BigDecimal bd = new BigDecimal(d);
Run Code Online (Sandbox Code Playgroud)

是不一样的:

BigDecimal bd = new BigDecimal("0.1");
Run Code Online (Sandbox Code Playgroud)

从转换doubleBigDecimal一般,你有什么不对的标志,你应该始终贯穿使用一种类型.

  • @regisxp:请发布您在.NET中使用的代码......您需要确切地确定*正在发生的事情.请注意我关于从"double"转换为"BigDecimal"的观点基本上是一个坏主意...... (3认同)
  • +1问题真的值得这么优雅的答案吗? (2认同)
  • @Anshu:我希望将来有类似问题的人会搜索HALF_UP或HALF_DOWN,找到这个并将它们与这个问题进行比较...... (2认同)