HALF_EVEN 四舍五入是为了什么?

What is HALF_EVEN rounding for?

我无法想象我需要在 Java 中使用 RoundingMode.HALF_EVEN 的情况。

这种舍入模式是做什么用的? 我想什么时候使用它?

请给我一些真实世界的例子。

当您执行多次舍入操作并希望累积结果是真正的平均值,而不是像 HALF_UP 或 HALF_DOWN 那样向上或向下倾斜时,它很有用。

具体来说,它对统计分析(您不希望结果被非随机平均系统污染)或任何需要随机平均的情况很有用。

RoundingMode.HALF_EVEN 总是舍入到下一个数字,就像任何其他舍入算法一样 - 只有一个例外:如果要舍入的数字恰好在 2 个数字(2.5、42.5、-4.5)之间,它不会将它四舍五入,而是将它四舍五入到偶数的邻居。以下是一些示例:

  • 3.2 -> 3
  • 3.4 -> 3
  • 3.5 -> 4
  • 4.5 -> 4
  • 5.5 -> 6
  • -7.5 -> -8

行为在 Javadoc:

中有详细描述

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

所以给定数字 4.5,它恰好位于 4 和 5 之间的数字范围的中间,当您调用时:

BigDecimal value1 = new BigDecimal("4.5").setScale(0, RoundingMode.HALF_EVEN);

运行时也需要确定要舍入哪个邻居,也就是说,它应该舍入到 4 还是 5?通常它会根据 4.5 更接近哪个值进行舍入,但在这种情况下它接近 both 个邻居。不过,它不会任意选择最终结果,而是选择偶数。这是 ROUND_HALF_EVEN 的行为。如果你愿意,你可以指定 ROUND_HALF_UP 并且最终结果将是 5,而不是 4。另外,请记住,关于如何舍入的决定是基于最终结果是什么(而不是在大小数的小数部分,正如您所假设的那样)。

引用 this 说:

Rounding mode to round towards the "nearest neighbor" unless both

邻居是等距的,在这种情况下,向偶数邻居舍入。

如果数字左边的数字与 RoundingMode.HALF_UP 一样 丢弃的分数是奇数;如果它是 RoundingMode.HALF_DOWN 的行为 甚至。请注意,这是统计上最小化的舍入模式 重复应用于一系列计算时的累积误差。 它有时被称为“银行家舍入”,主要用于 美国。这种舍入模式类似于用于 float 的舍入策略 和 Java.

中的双重算术
Example:

Input ->    rounded  
5.5   ->    6  
2.5   ->    2  
1.6   ->    2  
1.1   ->    1  
1.0   ->    1  
-1.0  ->    -1  
-1.1  ->    -1  
-1.6  ->    -2  
-2.5  ->    -2  
-5.5  ->    -6   

因此它向最近的值舍入,如果两者等距则向偶数舍入。

如果你有随机的负数和正数 HALF_UP 很好,净误差将趋于 0。HALF_UP 也更容易让人理解,并且经常用于金融。

但是,如果您知道自己有更多的正数(或负数),您就会产生偏差。 HALF_EVEN 和 HALF_ODD 试图通过选择是向上舍入还是向下舍入 0.5 来纠正这个问题,这取决于它更可能是偶数还是奇数。如果您有 50/50 的偶数和奇数分配,这在统计上更公平,但对于人类来说更难理解。