每当我需要为二分搜索之类的算法平均两个数字时,我总是这样做:
int mid = low + ((high - low) / 2);
我最近在这篇文章中看到了另一种方法,但我不明白。它说你可以用Java做到这一点:
int mid = (low + high) >>> 1;
或者这个在 C++ 中:
int mid = ((unsigned int)low + (unsigned int)high)) >> 1;
C++ 版本本质上使两个操作数都无符号,因此进行移位会导致算术移位而不是有符号移位。我了解这两段代码在做什么,但这如何解决溢出问题?我认为整个问题是中间值high + low
可能溢出?
编辑:
哦,呃。所有的答案都没有完全回答我的问题,但正是@John Zeringue 的回答让它点击了。我会在这里尝试解释。
Java 中的问题(high + low)/2
并不完全是high + low
溢出(它确实溢出,因为整数都是有符号的,但所有位仍然存在,并且没有信息丢失)。像这样取平均值的问题是除法。除法是对有符号值进行运算,因此您的结果将为负数。使用移位代替将除以二,但考虑位而不是符号(有效地将其视为无符号)。