簡體   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