BigDecimal.Divide 给出了错误的结果

BigDecimal.Divide gives incorrect result

我在使用 BigDecimal 执行除法时得到不正确的结果。 数字 1 = 221500.0 数字 2 = 12.0 这是我的代码片段:

BigDecimal d1 = new BigDecimal(String.valueOf(number1)).setScale(13, 4);
BigDecimal d2 = new BigDecimal(String.valueOf(number2)).setScale(13, 4);
return (d1.divide(d2, 13, 4 )).doubleValue();

18458.33333333332

如果我使用它提供的计算器执行相同的计算 18458.333333333333333333333333333

让我知道处理 BigDecimal 中的比例的任何问题。如果有人让我知道如何使用计算器得出相同的结果,那将会很有帮助。

您要求 divide() 要求 13 位精度,这就是它给您的。

然后您将其转换为 double 并注意到 double 无法处理该精度。

BigDecimal d1 = new BigDecimal(String.valueOf(221500.0)).setScale(13, BigDecimal.ROUND_HALF_UP);
BigDecimal d2 = new BigDecimal(String.valueOf(12.0)).setScale(13, BigDecimal.ROUND_HALF_UP);
BigDecimal d3 = d1.divide(d2, 13, BigDecimal.ROUND_HALF_UP);
System.out.println("BigDecimal: " + d3);
System.out.println("as double : " + d3.doubleValue());

输出

BigDecimal: 18458.3333333333333
as double : 18458.333333333332

如果您打算放弃使用 BigDecimal 获得的额外精度,为什么不直接在 double 中进行数学运算?


换句话说:
不要做 new BigDecimal(String.valueOf(doubleValue)).
使用 BigDecimal.valueOf(doubleValue).

设置d1d2的比例好像没什么意思
除非明确需要,否则尽可能晚进行舍入。

有些事情你应该做不同的事情。

如您所知,BigDecimal 是一个很棒的工具,因为:

  • 它可以精确地保留十进制数字,不像任何浮点表示,例如 doublefloat

  • 它可以处理任意大的十进制数,不像 intdoublefloat

然而,要让它发挥作用,您应该牢记以下几点:

  • 将值设置为 BigDecimal 时,始终 使用字符串表示形式,因为只有字符串表示形式会处理小数精度。例如, new BigDecimal(String.valueOf(number1)) 是个坏主意,如果数字是双精度数(无法处理精确的小数),那么您会将不精确的数字转换为 BigDecimal。

  • 创建 BigDecimal 时不限制精度。通常 BigDecimal 将保持输入的精度,即 new BigDecimal("3.234") 将具有 3 个小数位。

  • 请在每次划分后设置 roudingMode。有关可能的路由模式,请参阅 JavaDoc,HALF_EVEN 是通常用例的最佳选择。

  • 除法时一定要设置小数点精度,因为除法可能会导致无限小数。

考虑这个例子:

public class BigDecimalTest {

    public static void main(final String[] args) {
        final BigDecimal d1 = new BigDecimal("221500");
        final BigDecimal d2 = new BigDecimal("12");
        final BigDecimal result=d1.divide(d2,30,RoundingMode.HALF_EVEN);
        System.out.println(result);
    }

}

这给出了

18458.333333333333333333333333333333

要求所有 30 位小数。随意将 30 更改为 300,这给出

18458.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

比计算器好很多,不是吗? :)