文章理解自這裏算法
前提:計算機的運算器中只有加法器沒有減法器。數據在計算機中是二進制表示的。spa
想固然的原碼
表示法:
1:用符號位區分正負數
2:正數-正數 == 正數 + 正數的相反數:1 - 1 = 1 + (-1) = 0
.net
假如咱們有一個4位的機器,由於數字有正負數和零值,所以想固然的咱們把最高位設置爲符號位0表明正數,1表明負數,後面位爲二進制數值的表示,例如1:0001,-1:1001,這種表示法即爲原碼。
下面咱們來驗證原碼錶示法的實用性:
code
正數+正數:0001+0010=0011 (1+2=3)
√
零 + 零:0000+1000=1000 (+0+(-0)=-0)?
正數加負數:0001+1001=1010 (1+(-1)=-2)×
blog
從結果中咱們發現,當沒有減法器時這種想固然的數值存儲方法(原碼)並不能正確的計算減法。
那怎麼辦呢?
get
利用同餘概念的補碼
表示法:
在原碼錶示法中咱們試圖使用加一個數的相反數的方法解決減法問題,卻碰了壁。還有沒有能夠避開減法器的加法操做呢?是有的,那就是同餘法。class
基礎概念
模:這裏的模能夠理解成能夠表示的數的個數。好比四位二進制,能夠表示0000——1111,共16個數,那麼就是模16。一位二進制最大能夠表示的數是1,可是能夠表示兩個數,因此模2。基礎
同餘數:當前數 + 當前數的同餘數 = 模, 同餘數 = 模 - 當前數硬件
基本思想
對於數值有限制,有溢出的運算(模運算)來講,減去一個數,其實也至關於加上這個數的同餘數。二進制
栗子:
若是說如今時針如今停在10點鐘,那麼讓它指向八點鐘呢?
方法1:10點 - 2(小時) = 8(點),也就是倒回去(減去)兩個小時。
方法2:10點 + 10(小時)= 8(點),也就是走到明天8點。這裏的模就是12小時。
存儲表示:
- 不須要符號位
- n 位存儲的模 = n 2 n^2 n2:
來看一下這種表示方法的實用性:
正數 + 正數:0110 + 0010 = 1000 (6 + 2 = 8)
√
正數 + 同餘數:0110(6
)- 0010(2
)=0110(6
)+ 1110(14
)=10100(20
)×
:由於是4位存儲,因此只能獲得0100 = 4 ,因此√
看來。。。仍是錯的。可是!咱們看到按照這種算法得出的結果是10100,可是對於四位二進制數,最大隻能存放4位(硬件決定了),若是咱們低四位,正好是0100(4),正好是咱們想要的結果,至於最高位的‘1’,計算機會把他放入psw寄存器進位位中。8位機則會放在cy中,x86會放在cf中(這個咱們不做討論)
簡略記憶:
原碼
最高位爲符號位,0表明正數,1表明負數,非符號位爲該數字絕對值的二進制表示。
如:
127的原碼爲0111 1111
-127的原碼爲1111 1111
反碼
正數的反碼與原碼一致;
負數的反碼是對原碼按位取反,只是最高位(符號位)不變。
如:
127的反碼爲0111 1111
-127的反碼爲1000 0000
補碼
正數的補碼與原碼一致;
負數的補碼是該數的反碼加1。
如:
127的補碼爲0111 1111
-127的補碼爲1000 0001
總結一下就是:
正數的原碼、反碼、補碼是一致的;
負數的補碼是反碼加1,反碼是對原碼按位取反,只是最高位(符號位)不變;
計算機數字運算均是基於補碼的。