前言:
今天在看Collections集合類源碼中的二分查找的時候华匾,看到了“>>>”符合,并結(jié)合“>>”机隙,想做些總結(jié)蜘拉,順便復(fù)習(xí)下原碼萨西、反碼、補(bǔ)碼與負(fù)數(shù)的二進(jìn)制表示等相關(guān)知識旭旭。
概念:
“>>>”:無符號右移(不區(qū)分正負(fù)數(shù)谎脯,高位補(bǔ)0)
“>>”? :帶符號右移(正數(shù)高位補(bǔ)0,負(fù)數(shù)高位補(bǔ)1)
帶符號左移的概念也就清楚了持寄,值得注意的是穿肄,沒有無符號左移運(yùn)算符“<<<”!
原碼:
正數(shù):正數(shù)的原碼就是其絕對值的二進(jìn)制表示
負(fù)數(shù):負(fù)數(shù)的原碼就是其絕對值的二進(jìn)制表示际看,然后高位補(bǔ)1
例如:-1 的原碼是 10000000 00000000 00000000 00000001
? ? ? ? ? -2 的原碼是 10000000 00000000 00000000 00000010
反碼:
正數(shù):正數(shù)的反碼與原碼相同
負(fù)數(shù):負(fù)數(shù)的反碼等于其原碼除符號位以外的各位按位取反
例如:-1 的反碼是 11111111 11111111 11111111 11111110
? ? ? ? ? -2 的反碼是 11111111 11111111 11111111 11111101
補(bǔ)碼:
正數(shù):正數(shù)的補(bǔ)碼與原碼相同
負(fù)數(shù):負(fù)數(shù)的補(bǔ)碼等于其反碼的最低位加1
例如:-1 的補(bǔ)碼是 11111111 11111111 11111111 11111111
? ? ? ? ? -2 的補(bǔ)碼是 11111111 11111111 11111111 11111110
注意:二進(jìn)制計算機(jī)中的數(shù)字表示用的均是補(bǔ)碼
為什么需要補(bǔ)碼咸产?
在這里,我們用幾個簡單的計算來說明:
由于正數(shù)的原碼仲闽、反碼脑溢、補(bǔ)碼都是一樣的,下面我們只討論負(fù)數(shù)的計算赖欣,比如我們要計算:1-1
原碼計算:
1 - 1
= 00000000 00000000 00000000 00000001 + 10000000 00000000 00000000 00000001
= 10000000 00000000 00000000 00000010 = -3(10)屑彻,有問題!
反碼計算:
1 - 1
= 00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111110
= 11111111 11111111 11111111 11111111
= 10000000 0000000 0000000 0000000(其原碼)= - 0(10)顶吮,有問題社牲!問題在如何區(qū)分+0和-0上,因為在人的計算概念中悴了,0是沒有正負(fù)之分的搏恤。
補(bǔ)碼計算:
1 - 1
= 00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111111
= 00000000 00000000 00000000 00000000 = 0(10),正確湃交!
是不是很神奇熟空!
理解了以上的概念和運(yùn)算后,我們就可以理解位移運(yùn)算符了
我們還是以例子來說明搞莺,比如說我們用5和-5做說明:
“>>”:
5>>1 = 00000000 00000000 00000000 00000101 >> 1
? ? ? ? = 00000000 00000000 00000000 00000010
? ? ? ? = 2(10)
-5>>1 = 100000000 00000000 00000000 000000101(原碼)>>1
? ? ? ? ? = 11111111 11111111 11111111 11111010(反碼)>>1
? ? ? ? ? = 11111111 11111111 11111111 11111011(補(bǔ)碼)>>1
? ? ? ? ? = 11111111 11111111 11111111 11111101(補(bǔ)碼結(jié)果)
? ? ? ? ? = -3(10)
同樣的
-4>>1 = 10000000 00000000 00000000 00000100 >>1
? ? ? ? ? = 11111111 11111111 11111111 11111011 >>1
? ? ? ? ? = 11111111 11111111 11111111 11111100>>1
? ? ? ? ? = 11111111 11111111 11111111 11111110
? ? ? ? ? = -2(10)
有的人可能會對“補(bǔ)碼求10進(jìn)制數(shù)”的過程有些疑惑息罗,
比如對= 11111111 11111111 11111111 11111101(補(bǔ)碼結(jié)果)
? ? ? ? ? = -3(10)——為什么是-3?
其實(shí)我們倒回去運(yùn)算才沧,將其轉(zhuǎn)化為原碼就好了(對補(bǔ)碼再求一次補(bǔ)碼)
11111111 11111111 11111111 11111101(補(bǔ)碼)
= 10000000 00000000 00000000 00000010(反碼)
= 10000000 00000000 00000000 00000011(補(bǔ)碼的補(bǔ)碼迈喉,即原碼)
= -3(10)
又或者換另外一種說法,就是已知一個十進(jìn)制數(shù)的補(bǔ)碼x温圆,如何求這個十進(jìn)制數(shù)y呢挨摸?(由于正數(shù)的補(bǔ)碼與原碼一致,這里的討論均是討論該十進(jìn)制數(shù)為負(fù)數(shù)的情況)
有個公式大家可以參考下:
y = -(!x + 1)
其實(shí)也就是求補(bǔ)碼的數(shù)學(xué)表示捌木,可以解釋如下:
十進(jìn)制負(fù)數(shù) = 該十進(jìn)制負(fù)數(shù)的二進(jìn)制數(shù)按位取反后加1的相反數(shù)(有點(diǎn)繞口...)
不過油坝,對于計算來說還是很好用的!
對于無符號右移(“>>>”),其運(yùn)算規(guī)則跟“>>”一致澈圈,但是高位需補(bǔ)0彬檀!
比如:
-4>>>1
= 10000000 00000000 00000000 00000100 >>1
= 11111111 11111111 11111111 11111011 >>1
= 11111111 11111111 11111111 11111100 >>1
= 01111111 11111111 11111111 11111110
= 2147483646
驗證一番: