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)