今天樓主看源碼時(shí)看到了 Java 中的移位指令淘捡,很是困惑嘿辟,于是去查閱了下資料舆瘪,終于搞懂了,特此記錄如下红伦。
說(shuō)明:>>> 運(yùn)算符會(huì)用 0 填充高位英古,>> 會(huì)用符號(hào)位填充高位。
這條準(zhǔn)則在移位正數(shù)時(shí)我們看不出他的影響昙读,但是我們來(lái)看看負(fù)數(shù)召调。我舉個(gè)例子, -2 >> 1 和 -2 >>> 1。
System.out.println(-2 >> 1);
System.out.println(-2 >>> 1);
// 分別輸出下面的結(jié)果
-1
2147483647
納尼唠叛,-2 >>> 1 右移一位成了 2147483647只嚣。
我來(lái)為你解開(kāi)謎底。
首先我們來(lái)看看 -2 在計(jì)算機(jī)內(nèi)如何存儲(chǔ)艺沼。
System.out.println(Integer.toBinaryString(-2));
輸出
11111111111111111111111111111110
別害怕册舞,這是 -2 的補(bǔ)碼 表示,不明白的小伙伴可以自行百度一下障般,或者看一下微機(jī)原理的書(shū)调鲸。
我們?cè)倩仡櫼幌拢?strong>>>> 運(yùn)算符會(huì)用 0 填充高位,>> 會(huì)用符號(hào)位填充高位挽荡。
- 好藐石,下面我們來(lái)看,>>> 情況下右移一位定拟,用 0 補(bǔ)充高位則是
System.out.println(Integer.toBinaryString(-2>>> 1));
01111111111111111111111111111111
// 這是補(bǔ)碼的表示于微,我們得到他的真值為 1111111111111111111111111111111,化為十進(jìn)制為 2 ** 31 -1(等比數(shù)列求和公式啊办素,不懂得小伙伴回去看看數(shù)學(xué)書(shū))角雷,即 2147483647。
- 那么很簡(jiǎn)單了啊性穿,我們?cè)賮?lái)看 -2 >> 1勺三,用符號(hào)位補(bǔ)充高位,負(fù)號(hào)符號(hào)位為 -1需曾,
System.out.println(Integer.toBinaryString(-2>> 1 ));
11111111111111111111111111111111
11111111111111111111111111111111 這也是補(bǔ)碼的表示吗坚,我們對(duì)他 在取補(bǔ)碼 + 1 得到 他的真值為 10000000000000000000000000000001,即是 -1呆万。
總結(jié)一下商源,右移的數(shù)為正數(shù)時(shí), >> 和 >>> 沒(méi)有區(qū)別谋减,因?yàn)檎龜?shù)的符號(hào)位為 0 牡彻,右移的數(shù)為負(fù)數(shù)時(shí),>> 和 >>> 有所區(qū)別出爹,要加以區(qū)分庄吼。
參考資料:
Difference between >> and >>>
Bitwise and Bit Shift Operators