繁体   English   中英

Java,会(低+高)>> 1 溢出吗?

[英]Java, will (low + high) >> 1 overflow?

我知道>>用于已签名,而>>>用于未签名

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

Java,会(低+高)>>> 1 溢出吗?

安全整数中值公式

根据第二个链接,他们为什么得出结论: avg = (low & high) + ((low ^ high) >> 1); 会避免溢出吗?

为什么他们不能直接使用它 : (low + high) >> 1

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

是的, (low + high) >> 1如果总和足够高,可能会溢出。 如您所知, >>>用于无符号,因此它始终会在最重要的一侧移动0 事实证明,这在它确实溢出时非常重要。

即使有溢出,使用(low + high)的技巧是仍然保留信息。 如果它确实溢出,最大可能的数学总和仍然是Integer.MAX_VALUE * 2 ,如果 Java 有一个 unsigned int ,它仍然可以表示为 unsigned int 但是,再除以2,当使用无符号向右移位运算,我们可以之作为一个unsigned int, >>> 当右移1 ,这让我们将总和视为 unsigned int ,“不溢出” int

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

无论您使用的是>>>还是>> ,都有可能发生溢出。 所以两者都可以溢出。 但只有>>>才能很好地处理这个案子,正确地“不溢出”总和。

诀窍

avg = (low & high) + ((low ^ high) >> 1);

是在总和可能溢出时计算平均值的另一种方法。 这完全避免了溢出。 这将总和分解为两部分——“进位”位和“非进位”位。

当使用加法时,转移到下一个更重要的位的位是当两个位都被设置时—— low & high 通常情况下,这些位必须左移,但我们正在计算 2 个数字的平均值,所以我们最后也会右移。 最终结果:这里没有变化。

未承载的比特要么是一个1 ,如果比特是不同的或0 ,如果比特是相同的-这就是(low ^ high)来源于(XOR)。 此外,通常情况下,这些位不会移位,但我们正在计算 2 个数字的平均值,因此我们最终也会右移。 这种转变显示为>> 1 &^运算符不会溢出,因此>>在这里可以正常工作。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM