數(shù)值信息在計(jì)算機(jī)內(nèi)是采用二進(jìn)制編碼表示。數(shù)有正負(fù)之分,一般情況下,用"0"表示正號,"1"表示負(fù)號,符號位放在數(shù)的最高位。
例如,8位二進(jìn)制數(shù)A = (+1011011),B = (-1011011),它們在機(jī)器中可以表示為:
A:01011011
B:11011011
普蘭網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司2013年至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。
計(jì)算機(jī)中幾種常用的編碼----原碼、反碼和補(bǔ)碼。
1.原碼
將符號位數(shù)字化為0或1,數(shù)的絕對值與符號一起編碼,即所謂"符號-絕對值表示"的編碼,稱為原碼。
例如:
整數(shù):
X = +1011011,原碼:[X]原 = 01011011;
X = -1011011,原碼:[X]原= 11011011;
小數(shù):
對于一個(gè)帶符號的純小數(shù),它的原碼表示就是把小數(shù)點(diǎn)左邊一位用作符號位。
X = 0.1011,原碼:[X]原 = 0.1011;
X = -0.1011,原碼:[X]原 = 1.1011;
當(dāng)采用原碼表示法時(shí),編碼簡單直觀,與真值轉(zhuǎn)換方便。但原碼也存在一些問題,一是零的表示不唯一,因?yàn)椋篬+0] = 000···0,[-0] = 100···0 零有二義性,
給機(jī)器判零帶來麻煩。二是用原碼進(jìn)行四則運(yùn)算時(shí),符號位需要單獨(dú)處理,且運(yùn)算規(guī)則復(fù)雜。例如加法運(yùn)算,若兩數(shù)同號,兩數(shù)相加,結(jié)果取共同的符號;
若兩數(shù)異號,則要大數(shù)減去小數(shù),結(jié)果冠以大號的符號。此外,借位操作如果用計(jì)算機(jī)硬件來實(shí)現(xiàn)是很困難的。
2.反碼
反碼很少使用,但作為一種編碼方式和求補(bǔ)碼的中間碼,我們還是要學(xué)習(xí)一下的。
正數(shù)的反碼與原碼表示相同。
負(fù)數(shù)反碼的符號位與原碼相同(仍用1表示),其余各位取反(0變1,1變0)。例如:
X = +1100110, [X]原 = 01100110,[X]反 = +1100110;
X = -1100110,[X]原 = 11100110,[X]反 = 10011001;
X = +0000000,[X]原 = 00000000,[X]反 = 00000000;
X = -0000000,[X]原 = 10000000,[X]反 = 111111111;
和原碼一樣,反碼中的零的表示也不唯一。
當(dāng)X為純小數(shù)時(shí),反碼的表示如下:
X = 0.1011,[X]原 = 0.1011,[X]反 = 0.1011;
X = -0.1011,[X]原 = 1.1011,[X]反 = 1.0100;
3.補(bǔ)碼
(1)模數(shù)的概念
模數(shù)從物理意義上講,是某種計(jì)量器的容量。例如,我們?nèi)粘I钪杏玫降溺姳?,模?shù)就是12。鐘表計(jì)時(shí)的方式就是達(dá)到12就從零開始(扔掉一個(gè)12),這在數(shù)學(xué)上是一種"取模(或取余)運(yùn)算(mod)"。例如:14%12 = 2。
如果現(xiàn)在的準(zhǔn)確時(shí)間是6點(diǎn)整,而你的手表指向8點(diǎn),怎樣把表撥準(zhǔn)呢?可以有兩種方法:把表往后撥2小時(shí),或把表往前撥10小時(shí),效果是一樣的。即:
8-2 = 6
(8+10)%12 = 6
在模數(shù)系統(tǒng)中,8-2 = 8+10 (mod 12)
上式之所以成立,是因?yàn)?與10對模數(shù)12是互為補(bǔ)數(shù)的(2+10 = 12)。因此,可以認(rèn)可這樣一個(gè)結(jié)論:在模數(shù)系統(tǒng)中,一個(gè)數(shù)減去另一個(gè)數(shù),或者一個(gè)數(shù)加上一個(gè)負(fù)數(shù),等于第一個(gè)數(shù)加上第二個(gè)數(shù)的補(bǔ)數(shù):
8+(-2) = 8+10 (mod 12)
我們稱10為-2在模12下的"補(bǔ)碼"。負(fù)數(shù)采用補(bǔ)碼表示后,可以使加減法統(tǒng)一為加法運(yùn)算。
在計(jì)算機(jī)中,機(jī)器表示數(shù)據(jù)的字長是固定的。對于n位數(shù)來說,模數(shù)的大小是:n位數(shù)全為1,且末位再加1。實(shí)際上模數(shù)的值已經(jīng)超過了機(jī)器所能表示的數(shù)的范圍,因此模數(shù)在機(jī)器中是表示不出來的。若運(yùn)算結(jié)果大于模數(shù),則模數(shù)自動(dòng)丟掉,也就等于實(shí)現(xiàn)了取模運(yùn)算。
如果有n位整數(shù)(包括一位符號位),則它的模數(shù)為2^n;如果有n位小數(shù),小數(shù)點(diǎn)前一位為符號位,則它的模數(shù)為2。
***(2)補(bǔ)碼表示法***
由以上討論得知,對于一個(gè)二進(jìn)制負(fù)數(shù),可用其模數(shù)與真值做加法(模減去該數(shù)的絕對值)求得其補(bǔ)碼。
例: X = -0110 [X]補(bǔ) = 2^4 + (-0110) = 1010
X = -0.1011 [X]補(bǔ) = 2 + (-0.1011) = 1.0101
由于機(jī)器中不存在數(shù)的真值形式,用上述公式求補(bǔ)碼在機(jī)器中不易實(shí)現(xiàn),但從上式可推導(dǎo)出一個(gè)簡便方法。
"對于一個(gè)負(fù)數(shù),其補(bǔ)碼由該數(shù)反碼的最末位加1求得。"
"對于正數(shù)來說,其原碼、反碼、補(bǔ)碼形式相同。”
補(bǔ)碼的特點(diǎn)之一就是零的表示唯一。
[+0]補(bǔ) = 0 0 ···0 [-0]補(bǔ) = 1 1 ··· 1 + 1 = 1 0 0 ··· 0
|_____| |______| | |______|
n位 n位 | n位
|_ _ _ _ _ _ _ 自動(dòng)丟失
這種簡便的求補(bǔ)碼方法經(jīng)常被簡稱為"求反加1"。
(3)補(bǔ)碼的運(yùn)算規(guī)則
采用補(bǔ)碼表示的另一個(gè)好處就是當(dāng)數(shù)值信息參與算術(shù)運(yùn)算時(shí),采用補(bǔ)碼方式是最方便的。首先,"符號位可作為數(shù)值參加運(yùn)算,"最后仍可得到正確的結(jié)果符號,符號無需單獨(dú)處理;其次,采用補(bǔ)碼進(jìn)行運(yùn)算時(shí),減法運(yùn)算可轉(zhuǎn)換為加法運(yùn)算,簡化了硬件中的運(yùn)算電路。
例如:
計(jì)算67-10=?
[+67]原 = 01000011, [+67]補(bǔ) = [+67]原
[-10]原 = 10001010, [-10]補(bǔ) = 11110110
0 1 0 0 0 0 1 1 [+67]補(bǔ)
+ 1 1 1 1 0 1 1 0 [-10]補(bǔ)
——————————————
1 0 0 1 1 1 0 0 1 = 57
|____________________________ 最高位的進(jìn)位自然丟失
由于字長只有8位,因此加法最高位的進(jìn)位自然丟失,達(dá)到了取模效果(即丟掉了一個(gè)模數(shù))。
應(yīng)當(dāng)指出,"補(bǔ)碼運(yùn)算的結(jié)果仍為補(bǔ)碼。" 上例中,從結(jié)果符號位得知,結(jié)果為正,所以補(bǔ)碼即原碼,轉(zhuǎn)換成十進(jìn)制數(shù)為57。
如果結(jié)果為負(fù),則是負(fù)數(shù)的補(bǔ)碼形式,若要變成原碼,需要對補(bǔ)碼再求補(bǔ),即可還原為原碼。
例如:
10 - 67 = ?
[+10]原 = 00001010 = [+10]補(bǔ)
[-67]原 = 11000011 [-67]補(bǔ) = 10111101
0 0 0 0 1 0 1 0
+ 1 0 1 1 1 1 0 1
——————————
1 1 0 0 0 1 1 1
[結(jié)果]補(bǔ) = 11000111,[結(jié)果]原 = 10111001
所以結(jié)果的真值為-0111001,十進(jìn)制為-57。
以上兩個(gè)例子是否就可以說明補(bǔ)碼運(yùn)算的結(jié)果總是正確的呢?請看下面的例子:
例如:
85 + 44 = ?
0 1 0 1 0 1 0 1
+ 0 0 1 0 1 1 0 0
———————————
1 0 0 0 0 0 0 1
從結(jié)果的符號位可以看出,結(jié)果是一負(fù)數(shù)。但兩個(gè)整數(shù)相加不可能是負(fù)數(shù),問題出在什么地方呢?原來這是由于"溢出"造成的,即結(jié)果超出了一定位數(shù)的二進(jìn)制數(shù)所能表示的數(shù)的范圍。
以上內(nèi)容節(jié)選自清華大學(xué)出版社《C++語言程序設(shè)計(jì)(第4版)》