原碼、反碼、補(bǔ)碼
引用
今天給大家介紹介紹原碼、反碼以及補(bǔ)碼,這個(gè)作為一個(gè)程序開(kāi)發(fā)人員是有必要去了解和掌握的,為什么這么說(shuō)呢?比如你是一個(gè)嵌入式工程師或者C語(yǔ)言高級(jí)工程師、底層開(kāi)發(fā)工程師,那么你比如對(duì)它有所了解和掌握。
那么對(duì)于計(jì)算機(jī)存儲(chǔ)來(lái)說(shuō),一個(gè)數(shù)存在的3種格式,即原碼、反碼、補(bǔ)碼,而我們的計(jì)算機(jī)存儲(chǔ)數(shù)據(jù)的時(shí)候是采用二進(jìn)制的補(bǔ)碼形式存儲(chǔ),為什么所示補(bǔ)碼的形式呢?下面我會(huì)舉例子進(jìn)行一個(gè)驗(yàn)證。
聲明
一、以下測(cè)試是以1字節(jié)空間測(cè)試,即8位二進(jìn)制數(shù)。
二、原碼反碼補(bǔ)碼:站在二進(jìn)制角度看。
在學(xué)習(xí)這三個(gè)碼的時(shí)候,我們先來(lái)了解了解機(jī)器數(shù)和真值。
一、機(jī)器數(shù)和真值
1、機(jī)器數(shù)
一個(gè)數(shù)在計(jì)算機(jī)中的二進(jìn)制表示形式, 叫做這個(gè)數(shù)的機(jī)器數(shù)。機(jī)器數(shù)是帶符號(hào)的,在計(jì)算機(jī)用一個(gè)數(shù)的最高位存放符號(hào), 正數(shù)為0, 負(fù)數(shù)為1.比如,十進(jìn)制中的數(shù) +3 ,計(jì)算機(jī)字長(zhǎng)為8位,轉(zhuǎn)換成二進(jìn)制就是00000011。如果是 -3 ,就是 10000011 。那么,這里的 00000011 和 10000011 就是機(jī)器數(shù)。
2、真值
因?yàn)榈谝晃皇欠?hào)位,所以機(jī)器數(shù)的形式值就不等于真正的數(shù)值。例如上面的有符號(hào)數(shù) 10000011,其最高位1代表負(fù),其真正數(shù)值是 -3 而不是形式值131(10000011轉(zhuǎn)換成十進(jìn)制等于131)。所以,為區(qū)別起見(jiàn),將帶符號(hào)位的機(jī)器數(shù)對(duì)應(yīng)的真正數(shù)值稱(chēng)為機(jī)器數(shù)的真值。例如:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
二、原碼、反碼及補(bǔ)碼之間的區(qū)別和聯(lián)系
1、原碼
1.1 原碼的介紹
原碼就是符號(hào)位加上真值的絕對(duì)值, 即用第一位表示符號(hào), 其余位表示值。
在我們的認(rèn)知領(lǐng)域里,一般我們隊(duì)數(shù)一般分為正數(shù)和負(fù)數(shù),當(dāng)然在進(jìn)制這里也不例外,以二進(jìn)制為例,1就是代表的負(fù)數(shù),表明這個(gè)數(shù)值是一個(gè)負(fù)的,0就是代表的正數(shù),表明這個(gè)數(shù)值是一個(gè)正值。
+1(原碼) = 0000 0001
-1(原碼) = 1000 0001
通過(guò)這個(gè)例子你可以看到,對(duì)于一個(gè)二進(jìn)制來(lái)說(shuō),最高位就是符號(hào)位,1就是代表的負(fù)數(shù),0就是代表的正數(shù)。那么我們就可以算出一個(gè)8位的二進(jìn)制數(shù)它能表達(dá)的取值范圍就應(yīng)該是[11111111,01111111];即[-127,127];當(dāng)然這個(gè)對(duì)于學(xué)過(guò)C語(yǔ)言的同學(xué)就知道,一個(gè)char類(lèi)型,占一個(gè)字節(jié),也就是8位二進(jìn)制,書(shū)上給出的取值范圍是[-128,127];那這兩個(gè)為什么不一樣,后面我告訴你原因。
1.2 用原碼存儲(chǔ)數(shù)據(jù)
我就舉一個(gè)很特殊的例子來(lái)驗(yàn)證用原碼存儲(chǔ)數(shù)據(jù)是否可以
1-1 = ?
按照我們正常正確的思維來(lái)計(jì)算的話,那么結(jié)果毋庸置疑的是0.那么我們就來(lái)算算。
1-1 = 1 + (-1)
也就是說(shuō):
1 0000 0001
-1 1000 0001
+ _________________
1000 0010 轉(zhuǎn)換成十進(jìn)制為-2;
這個(gè)結(jié)果是不是和我么的思維相違背,所以得出結(jié)論是用原碼存儲(chǔ)數(shù)據(jù)不對(duì)。
2、反碼
2.1 反碼的介紹
反碼顧名思義就是反著來(lái),當(dāng)然,這里需要注意一點(diǎn)就是:
1、正數(shù)的原碼、反碼、補(bǔ)碼都一樣。
2、負(fù)數(shù)的反碼就是符號(hào)位不變,其他位在原碼的基礎(chǔ)上取反,即0變?yōu)?,1變?yōu)?.
原碼 反碼
+1 0000 0001 0000 0001
-1 1000 0001 1111 1110
+0 0000 0000 0000 0000
-0 1000 0000 1111 1111
可見(jiàn)如果一個(gè)反碼表示的是負(fù)數(shù), 人腦無(wú)法直觀的看出來(lái)它的數(shù)值. 通常要將其轉(zhuǎn)換成原碼再計(jì)算.
2.2 用反碼存儲(chǔ)數(shù)據(jù)驗(yàn)證
跟上面一樣,舉一個(gè)例子來(lái)驗(yàn)證計(jì)算機(jī)存儲(chǔ)數(shù)據(jù)的時(shí)候用反碼的形式進(jìn)行存儲(chǔ)是否可以
計(jì)算1-1 :
1-1 = 1 + (-1)
也就是說(shuō):
1 0000 0001
-1 1111 1110
+ _________________
1111 1111 轉(zhuǎn)換成十進(jìn)制為-0;
然而 +0 的反碼是 0000 0000
-0 的反碼是 1111 1111 取反得到 1000 0000
那么這里就出現(xiàn)了一個(gè)問(wèn)題:在計(jì)算機(jī)中對(duì)于0這個(gè)數(shù)存在了兩種格式,然而在我們的認(rèn)知領(lǐng)域里,0就是0 ,只有一種表達(dá)形式,然而如果計(jì)算機(jī)用反碼的形式存儲(chǔ)就不能解決+0 和 -0 以及 0 的問(wèn)題。所以得出結(jié)論,計(jì)算機(jī)存儲(chǔ)不能用反碼的形式存儲(chǔ)。
3、補(bǔ)碼
3.1 補(bǔ)碼的介紹
補(bǔ)碼的表示方法是:
正數(shù)的補(bǔ)碼就是其本身
負(fù)數(shù)的補(bǔ)碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變, 其余各位取反, 最后+1. (即在反碼的基礎(chǔ)上+1)
例如:
原碼 反碼 補(bǔ)碼
+1 0000 0001 0000 0001 0000 0001
-1 1000 0001 1111 1110 1111 1111
+0 0000 0000 0000 0000 0000 0000
-0 1000 0000 1111 1111 10000 0000
在最后一行中,-0的補(bǔ)碼得出來(lái)是一個(gè)9位的二進(jìn)制數(shù),由于我們測(cè)試的是8位,所以,應(yīng)該把最高位舍去,有讀者會(huì)問(wèn)我,為什么舍去高位,不舍去低位,那是因?yàn)閿?shù)據(jù)在存儲(chǔ)的時(shí)候是由高到低進(jìn)行一個(gè)存儲(chǔ)。所以-0的補(bǔ)碼應(yīng)該是0000 0000.
3.2 用補(bǔ)碼的形式進(jìn)行存儲(chǔ)
同樣的道理,我還是舉個(gè)例子
計(jì)算1-1 = 1 + (-1)
+1: 0000 0001
-1: 1111 1111
+ —————————————————
10000 0000 (8位,最高位丟棄)
得出的結(jié)果就是0,而且從3.1我們也可以清楚的看到+0 和 -0這兩個(gè)存儲(chǔ)的結(jié)果都是一樣的,即 0000 0000.所以,如果用補(bǔ)碼的形式存儲(chǔ)就把一切問(wèn)題都解決了。
結(jié)論:在計(jì)算機(jī)存儲(chǔ)數(shù)據(jù)時(shí),計(jì)算機(jī)是采用二進(jìn)制補(bǔ)碼的形式進(jìn)行存儲(chǔ)。
這里給大家一個(gè)很好的例子,通過(guò)代碼的形式來(lái)展示
#include <stdio.h>
int main(int argc, const char * argv[]) {
int x = 1;//定義一個(gè)int類(lèi)型的變量名為x的變量。
int y = ~x;//~這是取反符號(hào),后面在我博客會(huì)介紹
printf("%d\n",y);//打印輸出y的值
return 0;
}
運(yùn)行結(jié)果為:-2
Program ended with exit code: 0
總結(jié):
這篇文章主要就是介紹了原碼、反碼、補(bǔ)碼,驗(yàn)證了計(jì)算機(jī)存儲(chǔ)到底用的是什么形式的存儲(chǔ)。當(dāng)然這篇文章并沒(méi)有列舉比如八進(jìn)制、十進(jìn)制等他們的原碼、反碼、補(bǔ)碼,我相信讀者會(huì)舉一反三,因?yàn)槟憧梢园寻诉M(jìn)制、十進(jìn)制、十六進(jìn)制轉(zhuǎn)換成二進(jìn)制,那樣你什么都會(huì)了。
結(jié)尾
最后,希望讀者在讀文章的時(shí)候發(fā)現(xiàn)有錯(cuò)誤或者不好的地方,歡迎留言,我會(huì)及時(shí)更改,感謝你的閱讀和評(píng)論已經(jīng)點(diǎn)贊收藏。