深刻理解原碼,反碼,補碼的原理

深刻理解原碼,反碼,補碼的原理

預備知識

二進制,十六進制,二進制與十進制的轉化運算c++

根據馮諾依曼結構的運算器,只有加法運算器,沒有減法運算器算法

因此,計算機中不是直接作減法,是經過加法來實現的。因此就必須引入一個符號位設計

原碼,反碼,補碼 的產生就是爲了解決這個問題3d

原碼

最簡單的機器數表示法code

原碼:blog

最高位表示符號位,1表示負,0表示正class

其餘位存放該數的二進制的絕對值基礎

img

直接用原碼運算原理

0001+0010=0011    (1+2=3)正確
0000+1000=1000    ((+0)+(-0)=-0)
0001+1001=1010    (1+(-1)=-2)出錯
1001+1001= ?

原碼正數之間的加法一般不會出錯硬件

正數與負數相加,或負數與負數相加,問題就出現了

因此,原碼直觀易懂,易於正值轉換,但用來實現加減法的話,運算規則總歸是太複雜,因而反碼來了

反碼

原碼最大的問題就在於一個數加上他的相反數不等於零,反碼的設計思想就是爲了解決這一點

反碼:

正數的反碼=原碼

負數的反碼=原碼除符號位外,按位取反

图片描述

咱們試着用反碼運算

0001+1110=1111 (1+(-1)=(-0))  有點問題,也正確
1110+1101=1011 (-1)+(-2)=(-4) 兩個負數相加,出錯

負數相加出錯,問題不大,咱們只須要在兩個負數相加時,將兩個負數反碼包括符號位所有按位取反相加,而後再給他的符號位強置‘1’就能夠了。

反碼錶示法其實已經解決了減法的問題,他不只不會像原碼那樣出現兩個相反數相加不爲零的狀況,並且對於任意的一個正數加負數,計算結果是正確的

而後就有了補碼

補碼

補碼:

正數的補碼=原碼

負數的補碼=反碼+1

負數的補碼的另一種算法:

自低位向高位,尾數第一個1及其右部的0保持不變,左部取反,符號位不變

其實上面兩段話,都只是補碼的求法,而不是補碼的定義,基礎工做者並不會心血來潮的把反碼+1就定義爲補碼,只不過是補碼正好就等於反碼加1罷了

暫時先忘記書上那句負數的補碼等於它的反碼+1,咱們的理解陷入了誤區

這也是爲何《計算機組成原理》要**特地先講補碼,再講反碼

接下來咱們要重點講講補碼的思想

補碼的思想

爲了理解,先得引入同餘的思想

其實就是一個計量器的容量大小,好比鐘錶的模M=12

同餘 是指兩個整數A和B除以同一個正整數M,所得餘數相同,好比1點和13點,2點和14點就是同餘的,能夠寫做

1 = 13 mod (12), 2 = 14 mod (12)

若是說如今時針如今停在10點鐘,那麼何時時針會停在8點鐘呢?

這麼說吧,由於過去2個小時前是8點,因此將來10個小時候也是8點

也就是說:倒撥2小時 或 正撥10小時 都是八點鐘

10-2=8,(10+10)mod(12)=8

因此,10-2和10+10從另外一個角度來看是等效的,它都使時針指向了8點鐘

既然是等效的,那在時鐘運算中,減去一個數,其實就至關於加上另一個數(這個數與減數相加正好等於12,也就是同餘數)

我再次強調,原碼,反碼,補碼的引入是爲了解決作減法的問題。在原碼,反碼錶示法中,咱們把減法化爲加法的思惟是減去一個數,等於加上一個數的相反數,結果因爲引入符號位形成了各類問題

那你應該知道我要說什麼了,利用模和同餘的概念,咱們能夠使減法運算轉化爲加法運算

而如今,咱們不引入負數的概念,就能夠把減法當成加法來算

因此接下來咱們聊4位二進制數的運算,也沒必要急於引入符號位。由於補碼的思想,把減法當成加法時並非必需要引入符號位的。

並且咱們能夠經過下面的例子,也許能回答另外一個問題,爲何負數的符號位是‘1’,而不是正數的符號位是‘1’

四位二進制補碼運算實例

0110 - 0010 (6-2=4) 計算機中沒有減法器,不能直接算

可是如今你知道,減去一個數,能夠等同於加上另一個正數(同餘數)

那麼這個數是什麼呢?時鐘運算中咱們能夠看出這個數與減數相加正好等於模M=12

四位二進制數的(計量器)=四位二進制數最大容量=2^4=16=10000B

那麼2(0010)的同餘數,就等於10000-0010=1110(14)

既然如此

0110(6) - 0010(2) = 0110(6) + 1110(14) = 10100(16+4=20)

OK,咱們看到按照這種算法得出的結果是10100,可是對於四位二進制數,最大隻能存放4位(硬件決定),正好是0100(4),就是咱們想要的結果,至於最高位的1,計算機會把他放入psw寄存器進位位中。8位機則會放在cy中,x86會放在cf中(不做討論)

這個時候,咱們再想一想在四位二進制數中,減去2,就至關於加上它的同餘數14

可是減去2,從另一個角度來講,也是加上(-2)。即加上(-2)和加上14其實獲得的二進制結果除了進位位,結果是同樣的。

若是咱們把1110(14)的最高位看做符號位後就是(-2)的補碼,這可能也是爲何負數的符號位是‘1’而不是‘0’,

並且在有符號位的四位二進制數中,能表示的只有‘-8~7’,而無符號位數(14)的做用和有符號數(-2)的做用效果實際上是同樣的。

那正數的補碼呢?加上一個正數,加法器就直接能夠實現。因此它的補碼就仍是它自己。

图片描述

到這裏,咱們發現原碼,反碼的問題,補碼基本解決了。

作減法時,0001(1)+1111(-1)=0000,咱們不再須要一個1000來表示負0了,就把1000規定爲-8

負數與負數相加的問題也解決了1111(-1)+1110(-2)=1101(-3)

爲何能夠+1

而後咱們再來看看爲何負數的補碼的求法爲何是反碼+1

由於負數的反碼加上這個負數的絕對值正好等於1111,再加1,就是1000,也就是四位二進數的模

而負數的補碼是它的絕對值的同餘數,能夠經過模減去負數的絕對值,獲得他的補碼。

因此,負數的補碼就是它的反碼+1

算補碼的小技巧

若是咱們把-8當成負數的原點。那麼-5的補碼是多少呢?

-5 = -8 + 3

-5的補碼就是-8的補碼加3

1000(-8) + 0011(3) = 1011(-5)

也能夠記住-1的補碼是1111口算減法得出

1111(-1) - 0100(4) = 1011(-5)

對於八位加法器的話,能夠把-128當補碼原點。十六位能夠把-32768當補碼原點。

是的,128256(八位二進制數的模)的一半,3276865536(十六位二進數的模)的一半

也很方便有沒有,並且簡單的是

補碼原點老是最高位是‘1’,其餘位是‘0’

感謝閱讀

相關文章
相關標籤/搜索