原碼,反碼,補(bǔ)碼
原碼是十進(jìn)制整數(shù)的二進(jìn)制表示形式,最左邊的一位是符號(hào)位,0為正,1為負(fù)。當(dāng)我們使用原碼進(jìn)行數(shù)的計(jì)算時(shí),會(huì)發(fā)現(xiàn)如果數(shù)為正數(shù),可以正常計(jì)算,如果為負(fù)數(shù),就會(huì)出現(xiàn)問(wèn)題。
例如:
10000000是-0的原碼,現(xiàn)在要計(jì)算0+1,1的原碼為00000001,相加結(jié)果為10000001,轉(zhuǎn)換為十進(jìn)制是-1,而不是1,同理,我們使用-1的原碼10000001計(jì)算一下-1-1,就會(huì)是10000000,是0的原碼,不是-2,由此可知,我們?cè)谟迷a計(jì)算與負(fù)數(shù)有關(guān)的計(jì)算時(shí),會(huì)出現(xiàn)問(wèn)題。
因此,反碼出現(xiàn)了。反碼的計(jì)算規(guī)則是:正數(shù)的反碼與原碼相同,負(fù)數(shù)的反碼是符號(hào)位不變,其余位0變1,1變0。使用反碼之后,就可以計(jì)算負(fù)數(shù)有關(guān)的運(yùn)算了
例如:
計(jì)算-57+1,-57的原碼為1100 0111,反碼為1011 1000,1的反碼與原碼相同,為0000 0001,將二者相加,結(jié)果為1011 1001,我們?cè)賹⒎创a轉(zhuǎn)為原碼,得到1100 0110,正好是-56的原碼,所以,反碼一定程度上解決了負(fù)數(shù)計(jì)算的問(wèn)題。
但是,如果在計(jì)算中出現(xiàn)跨0的情況,如-1+2=1,又會(huì)出現(xiàn)新的問(wèn)題,這也是反碼的弊端
如:-1 的原碼為1000 0001,反碼為1111 1110 2的原碼反碼相同 為0000 0010,二者相加的結(jié)果為0000 0000(實(shí)際上是再向前進(jìn)一位 0001 0000 0000但這里考慮的是一字節(jié)的情況,所以只看8位。)由于符號(hào)位是0,所以原碼與反碼相同,所以相加結(jié)果是0 不是1。造成這個(gè)問(wèn)題的原因是,原碼中,0有兩種表示方式,即0000 0000和1000 0000,對(duì)應(yīng)反碼中0也有兩種表示方式,即0111 1111和0000 0000,因此,在涉及到跨0的運(yùn)算時(shí),結(jié)果往往會(huì)比實(shí)際的要少1.為了解決這個(gè)問(wèn)題,大佬們提出了補(bǔ)碼。
在補(bǔ)碼中,正數(shù)依舊是與其原碼相同,而負(fù)數(shù)的補(bǔ)碼可以理解為將其反碼向下錯(cuò)了一位
十進(jìn)制數(shù) 原碼 反碼 補(bǔ)碼
0 00000000(+0) 00000000(+0) 00000000
10000000(-0) 11111111(-0) 00000000
-1 10000001 11111110 11111111
-2 10000010 11111101 11111110
-3 10000011 11111100 11111101
-4 10000100 11111011 11111100
-5 10000101 11111010 11111011
如表格所示,將負(fù)數(shù)的反碼向下錯(cuò)一位,也就是在反碼的基礎(chǔ)上加一計(jì)算得到的,變成補(bǔ)碼,就解決了0在反碼有兩種表現(xiàn)形式的問(wèn)題,所以在涉及到跨0的計(jì)算時(shí),就可以正常運(yùn)算。
此外,由于補(bǔ)碼的計(jì)算將反碼向下錯(cuò)了一位,所以一定會(huì)多出一位,也就是1000 0000,他代表的數(shù)字是-128,-128沒(méi)有原碼和反碼。所以一字節(jié)的取值范圍,也規(guī)定為-128~127。
在了解原碼反碼補(bǔ)碼后,就可以解釋一些運(yùn)算。
1.隱式轉(zhuǎn)換
在java中 byte short int long所占用的字節(jié)數(shù)分別為1 2 4 8,再進(jìn)行隱式轉(zhuǎn)換時(shí),邏輯是在前面補(bǔ)夠?qū)?yīng)的0。
比如byte a=10;int b=a; byte類(lèi)型的10的補(bǔ)碼為0000 1010。當(dāng)執(zhí)行第二句代碼時(shí),系統(tǒng)會(huì)將他隱式轉(zhuǎn)換為int類(lèi)型 此時(shí)的補(bǔ)碼就變成了0000 0000 0000 0000 0000 0000 0000 1010。
2.強(qiáng)制轉(zhuǎn)換
強(qiáng)制轉(zhuǎn)換中的大轉(zhuǎn)小,邏輯是去掉相應(yīng)的位數(shù),小轉(zhuǎn)大的邏輯同上
如int a=200;byte b=(byte)a;a開(kāi)始為int型,補(bǔ)碼為0000 0000 0000 0000 0000 0000 1100 1000,byte只占一個(gè)字節(jié),所以只保留最后八位,即1100 1000,需要注意的是,第一位是符號(hào)位,所以強(qiáng)制轉(zhuǎn)換的結(jié)果應(yīng)為-56
3.邏輯與&(1為true 0為false)
在進(jìn)行邏輯與運(yùn)算時(shí),兩個(gè)數(shù)的補(bǔ)碼對(duì)應(yīng)位數(shù)上的數(shù)字若相同,則結(jié)果是1 反之是0
4.邏輯或 |
進(jìn)行邏輯或運(yùn)算時(shí),有1結(jié)果就是1,反之就是0
5.右移>>,左移<<,無(wú)符號(hào)右移>>>
左移時(shí),低位補(bǔ)0,左移幾位,低位補(bǔ)幾個(gè)0,相當(dāng)于原十進(jìn)制數(shù)字乘幾個(gè)2
左移時(shí),高位補(bǔ)0或1,右移幾位,高位的數(shù)字位補(bǔ)幾個(gè)0,符號(hào)位補(bǔ)與原數(shù)字相同的符號(hào),相當(dāng)于原十進(jìn)制數(shù)字除以幾個(gè)2
無(wú)符號(hào)右移與右移的區(qū)別在于,符號(hào)位無(wú)論原數(shù)字是正是負(fù),都補(bǔ)0

浙公網(wǎng)安備 33010602011771號(hào)