【发布时间】:2013-10-07 00:46:33
【问题描述】:
每当我需要对二分搜索等算法的两个数字进行平均时,我总是会这样做:
int mid = low + ((high - low) / 2);
我最近在this post 看到了另一种方法,但我不明白。它说你可以在 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 溢出(它确实溢出,因为整数都是有符号的,但所有位仍然存在,并且没有信息丢失)。像这样取平均值的问题是除法。除法是对有符号值进行运算,因此您的结果将为负数。使用移位代替将除以二,但考虑位而不是符号(有效地将其视为无符号)。
【问题讨论】:
-
Java 没有无符号整数。考虑一下如果你的
int溢出会发生什么?还要考虑>>>的作用。 -
我建议你尝试一下,看看它有什么不同。几十年来,这一直是一个已知问题,因此您可以查找它,但您将通过自己弄清楚它来了解更多信息。
标签: java c++ math bit-manipulation integer-overflow