简而言之,是一个技巧,它使用未使用的符号位来执行非负数的正确平均值。(high + low) >>> 1
在假设 和 都是非负数的情况下,我们确信最上面的位(符号位)为零。high
low
因此,两者和实际上都是31位整数。high
low
high = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
low = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
当您将它们加在一起时,它们可能会“溢出”到顶部。
high + low = 1000 0000 0000 0000 0000 0000 0000 0000
= 2147483648 as unsigned 32-bit integer
= -2147483648 as signed 32-bit integer
(high + low) / 2 = 1100 0000 0000 0000 0000 0000 0000 0000 = -1073741824
(high + low) >>> 1 = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
当然,Java不支持无符号整数,因此我们必须除以2(作为无符号整数)的最好方法是逻辑右移 。>>>
在具有无符号整数的语言(例如C和C++)中,它会变得更加棘手,因为您的输入可以是完整的32位整数。一种解决方案是:low + ((high - low) / 2)
最后,列举 、 和 :>>>
>>
/
-
>>>
是逻辑右移。它用零填充上面的位。
-
>>
是算术右移。它用原始顶部位的副本填充其上部。
-
/
是分裂。
数学:
-
x >>> 1
视为无符号整数并将其除以二。它向下舍入。x
-
x >> 1
视为有符号整数并将其除以 2。它四舍五入到负无穷大。x
-
x / 2
视为有符号整数并将其除以 2。它四舍五入为零。x