計(jì)算機(jī)中的數(shù)據(jù)都是以補(bǔ)碼的形式存放和計(jì)算!
原碼
將一個(gè)整數(shù)轉(zhuǎn)換成二進(jìn)制形式,就是其原碼。例如short a = 6; a 的原碼就是0000 0000 0000 0110;更改 a 的值a = -18; 此時(shí) a 的原碼就是1000 0000 0001 0010。
通俗的理解,原碼就是一個(gè)整數(shù)本來的二進(jìn)制形式。
反碼
- 對(duì)于正數(shù),它的反碼就是其原碼(原碼和反碼相同);
-
負(fù)數(shù)的反碼是將原碼中
除符號(hào)位以外的所有位(數(shù)值位)取反,也就是 0 變成 1,1 變成 0。
例如short a = 6; a 的原碼和反碼都是0000 0000 0000 0110;更改 a 的值a = -18; 此時(shí) a 的反碼是1111 1111 1110 1101。
補(bǔ)碼
- 對(duì)于正數(shù),它的補(bǔ)碼就是其原碼(原碼、反碼、補(bǔ)碼都相同);
-
負(fù)數(shù)的補(bǔ)碼是其反碼加 1。
例如short a = 6; a 的原碼、反碼、補(bǔ)碼都是0000 0000 0000 0110;更改 a 的值a = -18; 此時(shí) a 的補(bǔ)碼是1111 1111 1110 1110。
可以認(rèn)為,補(bǔ)碼是在反碼的基礎(chǔ)上打了一個(gè)補(bǔ)丁,進(jìn)行了一下修正,所以叫“補(bǔ)碼”。
原碼、反碼、補(bǔ)碼的概念只對(duì)負(fù)數(shù)有實(shí)際意義,對(duì)于正數(shù),原碼、反碼、補(bǔ)碼都是一樣的。
最后總結(jié)一下 6 和 -18 從原碼到補(bǔ)碼的轉(zhuǎn)換過程:

在計(jì)算機(jī)內(nèi)存中,整數(shù)一律采用補(bǔ)碼的形式來存儲(chǔ)。這意味著,當(dāng)讀取整數(shù)時(shí)還要采用逆向的轉(zhuǎn)換,也就是將補(bǔ)碼轉(zhuǎn)換為原碼。將補(bǔ)碼轉(zhuǎn)換為原碼也很簡(jiǎn)單:先減去 1,再將數(shù)值位取反即可。
補(bǔ)碼到底簡(jiǎn)化硬件電路的
由于整數(shù)在內(nèi)存中是以補(bǔ)碼表示的,那么計(jì)算機(jī)只要設(shè)計(jì)一種簡(jiǎn)單的、不用區(qū)分符號(hào)位和數(shù)值位的加法電路,就能同時(shí)實(shí)現(xiàn)加法和減法運(yùn)算,并且非常高效,極大簡(jiǎn)化了計(jì)算機(jī)的硬件電路。
補(bǔ)碼計(jì)算:
6 - 18 = 6 + (-18)
= [0000 0000 0000 0110]補(bǔ) +
[1111 1111 1110 1110]補(bǔ)
= [1111 1111 1111 0100]補(bǔ) ,負(fù)數(shù)減1
= [1111 1111 1111 0011]反
= [1000 0000 0000 1100]原
= -12
18 - 6 = 18 + (-6)
= [0000 0000 0001 0010]補(bǔ) +
[1111 1111 1111 1010]補(bǔ)
= [1 0000 0000 0000 1100]補(bǔ)
= [0000 0000 0000 1100]補(bǔ)
= [0000 0000 0000 1100]反
= [0000 0000 0000 1100]原
= 12
5 - 13 = 5 + (-13)
= [0000 0000 0000 0101]補(bǔ) +
[1111 1111 1111 0011]補(bǔ)
= [1111 1111 1111 1000]補(bǔ)
= [1111 1111 1111 0111]反
= [1000 0000 0000 1000]原
= -8
13 - 5 = 13 + (-5)
= [0000 0000 0000 1101]補(bǔ) +
[1111 1111 1111 1011]補(bǔ)
= [1 0000 0000 0000 1000]補(bǔ)
= [0000 0000 0000 1000]補(bǔ)
= [0000 0000 0000 1000]反
= [0000 0000 0000 1000]原
= 8
位運(yùn)算
1、“與” 運(yùn)算(&)
運(yùn)算規(guī)則: 兩個(gè)參與運(yùn)算的數(shù)據(jù),按照它們的二進(jìn)制位進(jìn)行運(yùn)算。
只有兩個(gè)位都是1的時(shí)候結(jié)果才是1,否則是0。 例如1&1=1,1&0=0,0&1=0,0&0=0
舉例: 3&5=? 首先將3換算成2二進(jìn)制數(shù),3是 0000_0011,5是 0000_0101,則
0000_0011
& 0000_0101
= 0000_0001
即結(jié)果是十進(jìn)制的1
補(bǔ)充:負(fù)數(shù)按補(bǔ)碼的形式參與 “與” 運(yùn)算。
用途:
1)將某些位的值變成0
比如 0010_1010,如果跟 0000_1100按位 "與",就是把高4位以及低2位變成0,結(jié)果如 0000_1000
2)檢測(cè)某個(gè)位的值是不是1
比如有個(gè)值是 0000_0101,它的每個(gè)位代表著一個(gè)開關(guān),0是關(guān)1是開,我怎么知道某個(gè)位上的值是什么?
比如和 0000_0001按位 "與" 就可以得到右邊第一位是不是1,檢測(cè)右邊第二位是否1可以跟 0000_0010 按位 "與",如此類推...
3)取一個(gè)數(shù)的某幾位的值(其實(shí)跟第二種用法差不多)
比如,有個(gè)值是 0010_0101,要取高4位,就跟 1111_0000 運(yùn)算得到 0010_0000;要取低4位,就跟
0000_1111 運(yùn)算得到 0000_0101;要取指定位上的值,只要跟那個(gè)位上是1的數(shù)進(jìn)行按位 "與" 就行了。
其實(shí)原理就是可以用1去試探,只有原來的值是1才會(huì)得到1,原來是0,也得到0,所以得到什么值表示了原來是什么值
2、“或” 運(yùn)算(|)
運(yùn)算規(guī)則: 將兩個(gè)要運(yùn)算的數(shù)據(jù),按照它們的二進(jìn)制位,進(jìn)行 “或” 運(yùn)算。
即只要有一個(gè)是1,結(jié)果就是1。*如:1|0=1,0|1=1,1|1=1,0|0=0
舉例: 3|5=? 換算一下,3是 0000_0011,5是 0000_0101,則
0000_0011
|0000_0101
=0000_0111
即結(jié)果是十進(jìn)制的7
補(bǔ)充:負(fù)數(shù)的按位 “或” 要轉(zhuǎn)換為補(bǔ)碼的形式再進(jìn)行計(jì)算。
用途:
1)把某個(gè)位上的值改成1
例如 0000_0101,要把右邊第二位改成1,只要和 0000_0010 按位 "或" 即可。
3、“異或” 運(yùn)算(^)
運(yùn)算規(guī)則: 異或,就是特殊的 “或”,0|0=0,0|1=1,1|0=1,1|1=0,簡(jiǎn)單而言,就是 相同為0,不同為1
舉例: 3^5,3轉(zhuǎn)成二進(jìn)制,則
0000_0011
^0000_0101
=0000_0110
即十進(jìn)制的6
用途:
1)讓一個(gè)數(shù)的位0變1,1變0(有人疑惑,這不是取反運(yùn)算符也可以嗎?,不同,這個(gè)可以按自己需要指定哪幾位)
比如有個(gè)值 0100_0101,我想翻轉(zhuǎn),則跟 1111_1111 進(jìn)行按位 "異或",得到 1011_1010
2)與0相異或,保留原值 ,1010_1110 ^ 0000 0000 = 1010_1110。
4、取反運(yùn)算(~)
運(yùn)算規(guī)則: 取反,很簡(jiǎn)單,就是0=1,1=0。它是單目運(yùn)算符
舉例: ~3
~0000_0011=1111_1100,即十進(jìn)制的252
5、左移運(yùn)算(<<)
正數(shù)負(fù)數(shù)都是相同的處理方式:高位溢出的丟棄,低位不足的補(bǔ)0
效果:值乘以2。但有些情況會(huì)溢出得到負(fù)數(shù)。
6、右移運(yùn)算(>>)
正負(fù)數(shù)的右移處理方式不同
正數(shù):高位補(bǔ)0,低位溢出的舍去
負(fù)數(shù):高位補(bǔ)1,低位溢出的舍去