BigDecimal乘法

Rak*_* KR 4 java bigdecimal

我尝试将两个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);
Run Code Online (Sandbox Code Playgroud)

我除了ans之外60.但我得到了,

Ans:59.999999999999994
Run Code Online (Sandbox Code Playgroud)

为什么会这样,我们如何解决它.

Mic*_*das 5

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

BigDecimal 不支持不能写为固定长度小数的数字.

来自BigDecimalJavadoc:

在除法的情况下,精确商可以具有无限长的十进制扩展; 例如,1除以3.如果商具有非终止十进制扩展并且指定了操作以返回精确结果,则抛出ArithmeticException.否则,返回除法的确切结果,与其他操作一样.

  • 虽然这通常是答案,但在这种情况下它不会有帮助,因为虽然"1.1"是第二个"BigDecimal"的精细字符串,你会用什么第一个? (2认同)

Pet*_*rey 5

问题是您有一个无法用 BigDecimal 表示的值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);
Run Code Online (Sandbox Code Playgroud)

印刷

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
Run Code Online (Sandbox Code Playgroud)

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