我想在Java中为任意两个整数x,y计算(x + y)/2
。如果x + y> 0,则天真的方式会遇到问题。 Integer.MAX_VALUE或< Integer.MIN_VALUE的。
番石榴IntMath
uses这种技巧:
public static int mean(int x, int y) {
// Efficient method for computing the arithmetic mean.
// The alternative (x + y) / 2 fails for large values.
// The alternative (x + y) >>> 1 fails for negative values.
return (x & y) + ((x ^ y) >> 1);
}
...但是这会向负无穷大方向发展,这意味着例程不符合像{-1,-2}这样的值的天真方式(给-2而不是-1)。
是否有任何相应的例程向0截断?
“只使用long
”不是我正在寻找的答案,因为我想要一个适用于长输入的方法。 BigInteger
也不是我正在寻找的答案。我不想要任何分支机构的解决方案。
答案 0 :(得分:2)
如果最低位不同(因此结果不准确且需要舍入),则需要将1
添加到结果中,并且结果中的符号位置位(结果为负,所以你想把这一轮改成圆形)。
所以以下内容应该(未经测试):
public static int mean(int x, int y) {
int xor = x ^ y;
int roundedDown = (x & y) + (xor >> 1);
return roundedDown + (1 & xor & (roundedDown >>> 31));
}
答案 1 :(得分:0)
为什么不执行(x-y)/2 + y
之类的操作,缩减为x/2 - y/2 + y = x/2 + y/2
?因此,如果x+y
为您提供上溢或下溢,请以(x-y)/2 + y
方式执行此操作。