1. 程式人生 > >5.5 除法的運算過程

5.5 除法的運算過程

繼續 如何 眼睛 似的 怎麽 註意 ddn 這一 地方

計算機組成

5 乘法器和除法器

5.5 除法的運算過程

技術分享圖片

在加、減、乘、除這樣的基本算數運算當中,除法是最為復雜的。因此,我們想要實現硬件的除法器,還是從最簡單的情況開始說起。

技術分享圖片

我們還是采用紙筆進行模仿除法運算的方式,來回顧一下除法的運算過程。這裏是兩個十進制的數,被除數是1001010,除數是1000。這是兩個經過精心挑選的數,用它們進行除法運算,運算的過程中只會出現0或者1,所以看上出又像是二進制表示的數。所以我們通過這個例子可以看出十進制的除法運算和二進制的除法運算之間的聯系。這個運算的過程,我們已經非常熟悉了,所以我們快速地來看一遍。

首先將除數和被除數,從高位開始對齊,然後將對齊的這部分進行一個減法,當我們發現減完的結果是一個正數,也就是所謂的夠減的時候,我們就在上面標一個1,然後把減完的差放在下面,再從被除數後面的位拿一個數下來,這時候我們用眼睛看一看就可以發現,現在這個數還不夠去減這個除數。

技術分享圖片

所以我們在上面標一個0,然後再多拿一位,還不夠減去除數。

技術分享圖片

那麽我們在最上面再標一個0,然後再拿一位下來。現在我們發現,這時候已經夠減這個除數了(1010 > 1000)。

技術分享圖片

好,那我們在這上面標一個1,然後把除數寫在這裏,再執行一次減法,減完的結果已經比除數小了(10 < 1000),而且被除數那裏也沒有多余的位可以拿下來繼續運算,這樣我們這個除法就已經完成了。

技術分享圖片

先得到最上面的這個數,就是這個除法運算的商;而最下面的這個數,我們稱為余數。如果用一個式子來表達這四個數的關系,那就是被除數等於商乘以除數再加上余數。當然我在描述這個除法運算的時候非常的口語化,而且也有人的智力因素參與其中。比如說用眼睛看一看夠不夠減之類的,這樣的描述過程是很難用硬件去實現的。想要設計一個硬件的除法器,首先我們要從硬件實現的 角度出發,來考慮如何描述除法的運算過程。那我們用這樣的方式再來看另一個例子。

技術分享圖片

這裏就是兩個二進制數的除法了。被除數是 00000111,這就是十進制的7;而除數是0010,這就是十進制的2。所以,這就是做7除以2。對於硬件實現,我們首先要考慮的是這個運算的操作數的寬度,這裏我們可以看到,被除數是一個8位寬的數,而除數是一個4位寬的數。因此,在這樣的情況下,即使高位是0,我們也不能將這個0省略,因為它們實實在在地在硬件中占據了位置。

技術分享圖片

很顯然,我們可以把被除數放在一個8位寬的寄存器當中,同時我們還要註意,被除數是在不斷的和除數進行減法的操作,在經過幾輪之後,減法的運算結果最後就產生了余數。所以,如果我們將每次減法運算的結果都放回到被除數的寄存器當中,那麽這個寄存器又可以被稱為余數寄存器,現在我們就有了第一個部件,就是一個8位寬的余數寄存器;然後,我們還需要一個部件來保存除數;還需要一個部件來保存商。

技術分享圖片

那我們在紙上進行除法運算的時候。第1步,會把除數抄寫到這裏,並將被除數當中最高的4位和這個除數進行對比。經過比較,我們發現被除數的這一部分是比除數小的(0000 < 0010)。所以,不能執行這個減法。因此,我們在與當前除數最低位對齊的這個地方,標上我們得到的第一位的商,也就是0。目前執行的這個過程,我們就稱為第一輪。然後我們會怎麽做?

技術分享圖片

我們接下來要做的就是把除數往右挪一個位置,把除數再抄一遍。好,我們把除數抄在這裏,如果我們忽略這些數字底下襯著的這些帶顏色的框,那它實際上和在紙上進行除法運算我們所寫的內容是一樣的;如果我們帶上了這個寫了除數的長條形的方框,那我們又可以發現這個除數0010好像是在這個方框中右移了一位,這樣我們就可以考慮在硬件上用一個帶右移的寄存器來實現這個功能。那麽這個時候又需要用被除數和除數進行一個減法運算了。

技術分享圖片

那現在夠不夠減呢?實際上還是不夠的(0000 < 0010)。其實我們不用去找應該對齊哪幾位進行減法的比較,如果我們直接把這個寫著除數的長條方框看成一個8位的寄存器的話,那就可以把其中沒有標明數字的地方都看做是0,每次都是把這個標著除數的8位的寄存器的內容和上面標著余數的8位寄存器的內容進行比較,那麽現在這個除數還是更大一些(0001 0000 > 0000 0111)。所以,這一輪也不能執行減法。這樣,我們在商這個位置再標一個0。我們要註意,在紙上運算時,我們直接就寫上了第二個0,而現在我們在硬件上只給商預留了4個位置,也就是說是一個4位的寄存器。所以,這個操作就好比將商的這個寄存器往左進行了一個移位,並在最右端補入了一個0,那這就是第二輪。

技術分享圖片

然後我們繼續,再將除數往右邊挪一位和被除數進行比較,現在還是除數更大(0000 1000 > 0000 0111)。所以,這一次還是不能執行減法,而商再寫上一個0,這就是第三輪。

技術分享圖片

我們再看下一輪。再向右移一位除數之後,我們發現,現在被除數更大了(0000 0111 > 0000 0100)。可以執行一次減法了,減完的結果就是0000 0011。因為執行了一次減法,所以我們在商對應的位置標上了1,也就相當於對這個商寄存器往左移動一位之後,在最右端補上了一個1。然後我們把這個減法的結果更新到余數寄存器當中去, 這就是第四輪。

技術分享圖片

但現在還沒有結束,我們還需要把除數再往右移一位,並和當前的余數進行比較, 我們發現還可以進行一次減法運算(因為余數大於除數:0000 0011 > 0000 0010)。所以,在最上面,我們再把商從最右邊移入一個1。然後,再回來看下邊,我們再執行一次減法,得到了一個結果為0000 0001,並把這個結果再更新到余數寄存器當中去,這就是第五輪。現在我們就已經得到了最終的結果。最上面是商的最終結果:0011;最下面是余數的最終結果:0000 0001,也就是1。0011是十進制的3,所以7除以2,商為3,余數為1,這樣的結果顯然是正確的。

我們再來整理一下這個例子。

對於被除數,我們選擇的是十進制的7;對於二進制,7可以用8個比特0000 0111來表示,而且被除數我們可以視為初始化時候的余數。

除數2,我們用4個比特的寄存器來保存,而且在運算的過程中,我們可以看作將除數不斷地右移,並和被除數進行相減。

對於余數,雖然它最終的結果很小,但是因為它可以與被除數共享一個寄存器。所以,我們也用8個比特來表示。

對於商,在這個例子中是3。我們要註意到的是,在運算過程中,它的每一個比特是從高到低,也就是從左往右依次生成的,可以視為不斷地左移而形成。在這裏我們也用4個比特的寄存器來保存。

我們要註意,這個位寬和乘法運算正好是相反的。在乘法當中,我們一般會約定乘數和被乘數的寬度是一樣的:如果兩個都是4位寬的,則乘積最多為8位寬。所以,在除法當中我們也用了類似的約定:如果被除數是8位寬,則除數和商都約定為4位寬。

現在我們就有了一個適合硬件實現的除法運算過程了。

技術分享圖片

從這個事例我們就能夠看出,除法運算確實是非常復雜。不過現在我們應該很有信心,只要我們能夠用適合硬件的方式把這個運算過程描述出來,我們就應該能夠把這個除法器設計出來。

5.5 除法的運算過程