计算机处理负数加法,怎么让加法器实现两个负数相加
請點評
我們已經(jīng)了解了計算機中正整數(shù)如何表示,加法如何計算,那么負(fù)數(shù)如何表示,減法又如何計算呢?本節(jié)討論這些問題.為了書寫方便,本節(jié)舉的例子都用8個bit表示一個數(shù),實際計算機做整數(shù)加減運算的操作數(shù)可以是8位、16位、32位甚至64位的.
要用8個bit表示正數(shù)和負(fù)數(shù),一種簡單的想法是把最高位規(guī)定為符號位(Sign Bit),0表示正1表示負(fù),剩下的7位表示絕對值的大小,這稱為Sign and Magnitude表示法.例如-1表示成10000001,+1表示成00000001.這樣用8個bit表示整數(shù)的取值范圍是-27-1~27-1,即-127~127.
采用這種表示法,計算機做加法運算需要處理以下邏輯:
如果兩數(shù)符號位相同,就把它們的低7位相加,符號位不變.如果低7位相加時在最高位產(chǎn)生進(jìn)位,說明結(jié)果的絕對值大于127,超出7位所能表示的數(shù)值范圍,這稱為溢出(Overflow)[24],這時通常把計算機中的一個標(biāo)志位置1表示當(dāng)前運算產(chǎn)生了溢出.
如果兩數(shù)符號位不同,首先比較它們的低7位誰大,然后用大數(shù)減小數(shù),結(jié)果的符號位和大數(shù)相同.
那么減法如何計算呢?由于我們規(guī)定了負(fù)數(shù)的表示,可以把減法轉(zhuǎn)換成加法來計算,要計算a-b,可以先把b變號然后和a相加,相當(dāng)于計算a+(-b).但如果兩個加數(shù)的符號位不同就要用大數(shù)的絕對值減小數(shù)的絕對值,這一步減法計算仍然是免不了的.我們知道加法要進(jìn)位,減法要借位,計算過程是不同的,所以除了要有第 1 節(jié) "為什么計算機用二進(jìn)制計數(shù)"提到的加法器電路之外,還要另外有一套減法器電路.
如果采用Sign and Magnitude表示法,計算機做加減運算需要處理很多邏輯:比較符號位,比較絕對值,加法改減法,減法改加法,小數(shù)減大數(shù)改成大數(shù)減小數(shù)……這是非常低效率的.還有一個缺點是0的表示不唯一,既可以表示成10000000也可以表示成00000000,這進(jìn)一步增加了邏輯的復(fù)雜性,所以我們迫切需要重新設(shè)計整數(shù)的表示方法使計算過程更簡單.
本節(jié)介紹一種二進(jìn)制補碼表示法,為了便于理解,我們先看一個十進(jìn)制的例子:
167-52=167+(-52)=167+(999-52)-1000+1=167+947-1000+1=1114-1000+1=114+1=115
167-52 → 減法轉(zhuǎn)換成加法 167+(-52) → 負(fù)數(shù)取9的補碼表示 167+947 → 114進(jìn)1 → 高位進(jìn)的1加到低位上去,結(jié)果為115
在這個例子中我們用三位十進(jìn)制數(shù)字表示正數(shù)和負(fù)數(shù),具體規(guī)定如下:
表14.5. 9's Complement表示法
數(shù)值 補碼表示
首先-52要用999-52表示,就是947,這稱為取9的補碼(9's Complement);然后把167和947相加,得到114進(jìn)1;再把高位進(jìn)的1加到低位上去,得115,本來應(yīng)該加1000,結(jié)果加了1,少加了999,正好把先前取9的補碼多加的999抵消掉了.我們本來要做167-52的減法運算,結(jié)果變成做999-52的減法運算,后者顯然要容易一些,因為沒有借位.這種補碼表示法的計算規(guī)則用一句話概括就是:負(fù)數(shù)用9的補碼表示,減法轉(zhuǎn)換成加法,計算結(jié)果的最高位如果有進(jìn)位則要加回到最低位上去.要驗證這條規(guī)則得考慮四種情況:
兩個正數(shù),相加得正
一正一負(fù),相加得正
一正一負(fù),相加得負(fù)
兩個負(fù)數(shù),相加得負(fù)
我們舉的例子驗證了第二種情況,另外三種情況請讀者自己驗證,暫時不考慮溢出的問題,稍后會講到如何判定溢出.
上述規(guī)則也適用于二進(jìn)制: 負(fù)數(shù)用1的補碼(1's Complement)表示,減法轉(zhuǎn)換成加法,計算結(jié)果的最高位如果有進(jìn)位則要加回到最低位上去 .取1的補碼更簡單,連減法都不用做,因為1-1=0,1-0=1,取1的補碼就是把每個bit取反,所以1的補碼也稱為反碼.比如:
00001000-00000100 → 00001000+(-00000100) → 00001000+11111011 → 00000011進(jìn)1 → 高位進(jìn)的1加到低位上去,結(jié)果為00000100
1's Complement表示法相對于Sign and Magnitude表示法的優(yōu)勢是非常明顯的:不需要把符號和絕對值分開考慮,正數(shù)和負(fù)數(shù)的加法都一樣算,計算邏輯更簡單,甚至連減法器電路都省了,只要有一套加法器電路,再有一套把每個bit取反的電路,就可以做加法和減法運算.如果8個bit采用1's Complement表示法,負(fù)數(shù)的取值范圍是從10000000到11111111(-127~0),正數(shù)是從00000000到01111111(0~127),仍然可以根據(jù)最高位判斷一個數(shù)是正是負(fù).美中不足的是0的表示仍然不唯一,既可以表示成11111111也可以表示成00000000,為了解決這最后一個問題,我們引入2's Complement表示法.
2's Complement表示法規(guī)定:正數(shù)不變,負(fù)數(shù)先取反碼再加1.如果8個bit采用2's Complement表示法,負(fù)數(shù)的取值范圍是從10000000到11111111(-128~-1),正數(shù)是從00000000到01111111(0~127),也可以根據(jù)最高位判斷一個數(shù)是正是負(fù),并且0的表示是唯一的,目前絕大多數(shù)計算機都采用這種表示法.為什么稱為" 2的補碼 "呢?因為對一位二進(jìn)制數(shù)b取補碼就是1-b+1=10-b,相當(dāng)于從2里面減去b.類似地,要表示-4需要對00000100取補碼,11111111-00000100+1=100000000-00000100,相當(dāng)于從28里面減去4.2's Complement表示法的計算規(guī)則有些不同:減法轉(zhuǎn)換成加法,忽略計算結(jié)果最高位的進(jìn)位,不必加回到最低位上去.請讀者自己驗證上一節(jié)提到的四種情況下這條規(guī)則都能算出正確結(jié)果.
8個bit采用2's Complement表示法的取值范圍是-128~127,如果計算結(jié)果超出這個范圍就會產(chǎn)生溢出,例如:
圖14.3. 有符號數(shù)加法溢出
如何判斷產(chǎn)生了溢出呢?我們還是分四種情況討論:如果兩個正數(shù)相加溢出,結(jié)果一定是負(fù)數(shù);如果兩個負(fù)數(shù)相加溢出,結(jié)果一定是正數(shù);一正一負(fù)相加,無論結(jié)果是正是負(fù)都不可能溢出.
圖14.4. 如何判定溢出
從上圖可以得出結(jié)論: 在相加過程中最高位產(chǎn)生的進(jìn)位和次高位產(chǎn)生的進(jìn)位如果相同則沒有溢出,如果不同則表示有溢出 .邏輯電路的實現(xiàn)可以把這兩個進(jìn)位連接到一個異或門,把異或門的輸出連接到溢出標(biāo)志位.
3.4. 有符號數(shù)和無符號數(shù) 請點評
前面幾節(jié)我們用8個bit表示正數(shù)和負(fù)數(shù),講了三種表示法,每種表示法對應(yīng)一種計算規(guī)則,這稱為有符號數(shù)(Signed Number);如果8個bit全部表示正數(shù)則取值范圍是0~255,這稱為無符號數(shù)(Unsigned Number).其實計算機做加法時并不區(qū)分操作數(shù)是有符號數(shù)還是無符號數(shù),計算過程都一樣,比如上面的例子也可以看作無符號數(shù)的加法:
圖14.5. 無符號數(shù)加法進(jìn)位
如果把這兩個操作數(shù)看作有符號數(shù)-126和-8相加,計算結(jié)果是錯的,因為產(chǎn)生了溢出;但如果看作無符號數(shù)130和248相加,計算結(jié)果是122進(jìn)1,也就是122+256,這個結(jié)果是對的.計算機的加法器在做完計算之后,根據(jù)最高位產(chǎn)生的進(jìn)位設(shè)置 進(jìn)位標(biāo)志 ,同時根據(jù)最高位和次高位產(chǎn)生的進(jìn)位的異或設(shè)置 溢出標(biāo)志 .至于這個加法到底是有符號數(shù)加法還是無符號數(shù)加法則取決于程序怎么理解了,如果程序把它理解成有符號數(shù)加法,下一步就要檢查溢出標(biāo)志,如果程序把它理解成無符號數(shù)加法,下一步就要檢查進(jìn)位標(biāo)志.通常計算機在做算術(shù)運算之后還可能設(shè)置另外兩個標(biāo)志,如果計算結(jié)果的所有bit都是零則設(shè)置 零標(biāo)志 ,如果計算結(jié)果的最高位是1則設(shè)置 負(fù)數(shù)標(biāo)志 ,如果程序把計算結(jié)果理解成有符號數(shù),也可以檢查負(fù)數(shù)標(biāo)志判斷結(jié)果是正是負(fù).
[24] 有時候會進(jìn)一步細(xì)分,把正整數(shù)溢出稱為上溢(Overflow),負(fù)整數(shù)溢出稱為下溢(Underflow),詳見strtol(3).
◆◆
評論讀取中....
請登錄后再發(fā)表評論!
◆◆
修改失敗,請稍后嘗試
總結(jié)
以上是生活随笔為你收集整理的计算机处理负数加法,怎么让加法器实现两个负数相加的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IAR集成开发环境的使用
- 下一篇: 李飞飞:在物体识别之后,计算机视觉还要多