我想我发现了一个错误:
MathContext mathContext = new MathContext(5, RoundingMode.HALF_UP);
result = BigDecimal.valueOf(0.004798).round(mathContext); // fails
// result is 0.004798!!! (same value)
Run Code Online (Sandbox Code Playgroud)
我不得不使用以下替代方案:
BigDecimal bigDecimal = BigDecimal.valueOf(0.004798);
BigDecimal new_divisor = BigDecimal.valueOf(1, 5);
bigDecimal_array = bigDecimal.divideAndRemainder(new_divisor);
MathContext mathContext = new MathContext(5, RoundingMode.HALF_UP);
result = bigDecimal.subtract(bigDecimal_array[1], mathContext);
result = result.stripTrailingZeros();
Run Code Online (Sandbox Code Playgroud)
在我看来,这个错误(如果是这样的话)非常危险。
不,没有错误。您只是误解了“精确”的含义。
要返回的总位数由 MathContext 的精度设置指定;这决定了结果的精度。数字计数从精确结果的最左边的非零数字开始。
(强调我的)。
在这种情况下,您有 4 位数字。因此任何大于或等于 4 的精度都不会影响舍入。
与之比较
result = BigDecimal.valueOf(0.004798).round(new MathContext(3, RoundingMode.HALF_UP));
result ==> 0.00480
Run Code Online (Sandbox Code Playgroud)
或与
jshell> result = BigDecimal.valueOf(1.004798).round(new MathContext(5, RoundingMode.UP));
result ==> 1.0048
Run Code Online (Sandbox Code Playgroud)
其行为如您所期望的那样。