大数乘法

BigDecimal Multiplication

我尝试将两个 BigDecimal 值与 multiply 方法相乘,如下所示,

BigDecimal dur = BigDecimal.valueOf(60/1.1);
BigDecimal bal = BigDecimal.valueOf(1.1);

BigDecimal ans  = dur.multiply(bal);

System.out.println("Ans:"+ans);

我将 ans 排除为 60。但我明白了,

Ans:59.999999999999994

为什么会这样,我们该如何解决。

您需要使用 String 构造函数而不是 double 构造函数。 60/1.1 没有 String 表示,因为它是 54.(54).

BigDecimal不支持不能写成定长小数的数字。

来自 BigDecimal Javadoc:

In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.

问题是您的值无法在 double 中表示,但也无法在 BigDecimal 中表示,因此您必须应用合理的舍入以获得预期的解决方案。

double d = 60 / 1.1 * 1.1;
System.out.println("double without rounding: " + d);
System.out.printf("double With rounding %.2f%n", d);

BigDecimal bd = BigDecimal.valueOf(60).divide(BigDecimal.valueOf(1.1), 9, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(1.1));
System.out.println("BigDecimal without rounding: " + bd);
System.out.printf("BigDecimal with rounding %.2f%n", bd);
// or
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("BigDecimal with rounding: " + bd);

打印

double without rounding: 60.0
double With rounding 60.00
BigDecimal without rounding: 59.9999999995
BigDecimal with rounding 60.00
BigDecimal with rounding: 60.00

注意:double 恰好对这些值进行了正确舍入并给出了正确答案。但是,选择不同的组合,它将是不正确的。例如54.545454545454545 * 1.1 => 60.00000000000001