Java,威尔(低和高)>&燃气轮机;1溢出?

Java,威尔(低和高)>&燃气轮机;1溢出?,java,overflow,average,bitwise-operators,Java,Overflow,Average,Bitwise Operators,我知道>表示已签名,而>>表示未签名 没有回答我问题的类似问题: 根据第二个链接,为什么他们得出结论: avg=(低&高)+(低^高)>>1将避免溢出 为什么他们不能用这个来代替:(低+高)>>1 (这是用于java中的二进制搜索)是的,(低+高)>>1如果总和足够高,可能会溢出。正如您所知,>用于unsigned,因此它总是在0的最有效侧移动。这对于防止溢出非常重要 即使溢出,使用(低+高)的诀窍是信息仍然保留。如果它确实溢出,则最大可能的数学和仍然是Integer.MAX_VALUE*2

我知道
>
表示已签名,而
>>
表示未签名

没有回答我问题的类似问题:

根据第二个链接,为什么他们得出结论:
avg=(低&高)+(低^高)>>1将避免溢出

为什么他们不能用这个来代替:
(低+高)>>1

(这是用于java中的二进制搜索)

是的,
(低+高)>>1
如果总和足够高,可能会溢出。正如您所知,
>
用于unsigned,因此它总是在
0
的最有效侧移动。这对于防止溢出非常重要

即使溢出,使用
(低+高)
的诀窍是信息仍然保留。如果它确实溢出,则最大可能的数学和仍然是
Integer.MAX_VALUE*2
,如果Java有,它仍然可以表示为无符号的
int
。但是我们可以使用无符号右移运算符,
将总和除以2时,将其视为无符号整数。当位向右移动
1
时,这允许我们将总和视为无符号
int
,“取消溢出”int

如果总和溢出,在此处使用
>
将不起作用,因为它将溢出为负数,
>
将在
1
中移动,保持值为负数。这将导致不正确的平均值计算(2个正数,其总和溢出将导致负平均值)

无论您使用的是
>>
还是
>
,都有可能出现溢出。所以两者都可能溢出。但是只有
>
才能很好地处理这个问题,正确地“解除”总数的溢出

诀窍

avg = (low & high) + ((low ^ high) >> 1);
是计算总和可能溢出时的平均值的另一种方法。这完全避免了溢出。这将总和分解为两部分——“进位”和“非进位”

使用加法运算时,当两个位都设置为--
低和高
时,转入下一个更高有效位的位。通常情况下,这些位必须向左移位,但我们计算的是2个数字的平均值,所以我们最后也要向右移位。最终结果是:这里没有变化

如果位不同,则未携带的位为
1
,如果位相同,则为
0
——这就是
(低)^高)
的来源(异或)。通常情况下,这些位不会移位,但我们计算的是2个数字的平均值,所以我们最后也会向右移位。此班次显示为
>1
&
^
运算符不会溢出,因此
>
在这里可以正常工作

示例:1100(12)和1010(10)的平均值

1100 & 1010 = 1000
1100 ^ 1010 = 0110, 0110 >> 1 = 0011
1000 + 0011 = 1011 (11)