为什么 BigDecimal 除法中的 RoundingMode.HALF_EVEN 将 0.45 舍入到 0.5?

Seb*_*ian 1 java numeric rounding bigdecimal

舍入模式HALF_EVEN应该将以 5 结尾的(十进制)数字舍入为最接近的甚至不太精确的数字(例如,4.5 舍入为 4,而 5.5 舍入为 6)。

现在看来Java的划分BigDecimal并不遵守这个规则;以下代码将其四舍五入为 0.45 至 0.5:

import java.math.*;

class Round {
    public static void main(String[] args) {
        BigDecimal five = BigDecimal.valueOf(5);
        BigDecimal eleven = BigDecimal.valueOf(11);
        BigDecimal x = five.divide(eleven, 1, RoundingMode.HALF_EVEN);
        System.out.println(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出0.5 请注意,5/11 = 0.4545454545...因此,当查看小数点后的前两位数字 0.45 时,我们显然希望看到四舍五入到最接近的偶数邻居,即 0.40,而不是 0.50。

谁能解释一下吗?

(如果重要的话,我正在运行java -version= openjdk版本“11.0.15”2022-04-19)

笔记:

  1. 这不是在将值放入 BigDecimal之前进行舍入;而是将值放入 BigDecimal 中。事实上,使用字符串构造函数时结果没有改变
     BigDecimal five = new BigDecimal("5");
     BigDecimal eleven = new BigDecimal("11");
     BigDecimal x = five.divide(eleven, 1, RoundingMode.HALF_EVEN);
Run Code Online (Sandbox Code Playgroud)
  1. 它也不取决于我们舍入的比例(只要比例是奇数),并且您可以将数字放大(例如,舍入 500/11)。

Swe*_*per 5

HALF_EVEN

向“最近邻居”舍入,除非两个邻居等距,在这种情况下,向偶数邻居舍入。

因此需要首先判断两个邻居是否等距。

所以当查看小数点后的前两位数字时......

这不足以确定该值是否与两个邻居等距,在本例中为 0.4 和 0.5。在这种情况下,我们需要再看一位数字。

在 5/11 的情况下,5/11 更接近 0.5(距离 = 0.045454545...)而不是 0.4(距离 = 0.0545454...),因此不应用“向偶数邻居舍入”,并且“舍入”朝向“最近的邻居””