天天看點

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

本節書摘來自華章計算機《計算機系統:核心概念及軟硬體實作(原書第4版)》一書中的第3章,第3.1節,作者:[美] j. 斯坦利·沃法德(j. stanley warford)著, 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

早期的計算機是機電式的,即所有計算是通過稱為繼電器(relay)的移動開關來實作的。哈佛大學的howard h. aiken(霍華德·艾肯)于1944年建造的mark i計算機就是這種類型的機器。這個項目上,aiken獲得了國際商用機器公司(ibm)總裁thomas j. watson(托馬斯·沃森)的資金支援。當時,mark i計算機中的繼電器比加法電腦中的機械齒輪計算速度快得多。

甚至在mark i完成之前,艾奧瓦州立大學的john v. atanasoff(約翰·阿塔納索夫)已經構造完成了一台用于解線性方程的電子計算機。1941年,john w. mauchly(約翰·莫齊利)通路atanasoff的實驗室,1946年與賓夕法尼亞大學的j. presper eckert(普雷斯伯·埃克特)合作建造了著名的電子數值積分計算機(eniac)。相比于mark i繼電器的每秒10次,eniac的19 000個真空管每秒可以執行5000次加法。與eniac一樣,現代計算機也是電子的,不過執行計算的是內建電路(ic)而不是真空管。每個ic中有數千個與收音機中一樣的半導體。

3.1.1二進制存儲器

電子計算機的存儲器不能直接存儲數字和字母,它們隻能存儲電子信号。當cpu從記憶體讀取資訊時,它檢測到一個信号,其電壓等于兩節手電筒電池産生的電壓。

計算機記憶體有一個最顯著的性質:每個存儲位置包含一個高電平信号或者低電平信号,絕不會是兩者之間的其他信号。存儲位置就像是懷孕一樣,要麼懷了要麼沒懷,沒有折中的可能。

數字(digital)這個詞意味着存儲在記憶體中的信号隻能有固定數量的數值。二進制意味着僅有兩個可能的值。實際上,現在市場上所有計算機都是二進制的,是以每個存儲位置包含一個高電平或者一個低電平,每個位置的狀态也被描述為開或關,或者描述為包含1或0。

每個存儲單元稱為二進制數字(binary digit)或位(bit,也譯作比特)。1位隻能是1或0,絕不可能是其他諸如2、3、a或z之類,這是基本概念。計算機存儲器中存儲的每條資訊,不管是你的信用卡透支總額還是你的街道位址,都是以二進制1和0的形式存儲的。

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

實際上,計算機存儲器中的位被組合在一起形成單元(cell)。例如,一台7位的計算機會以如圖3-1所示的每7位組成一組的方式存儲它的資訊。你可以把單元想作一組方框,每個方框包含一個1或0,除此之外什麼都沒有。圖3-1c的前兩行是不可能的,因為有些方框中的值不是0或1,最後一行也是不可能的,因為每個方框必須包含一個值。存儲位不能為空。

不同計算機的每個單元中的位數不同,然而現在大多數計算機的每個單元為8位。本章給出幾個單元大小不同的例子來說明普适原理。

諸如數字和字母這樣的資訊必須以二進制的形式表示才能存儲到存儲器中。用于存儲資訊的表示方式叫作編碼(code)。本節給出存儲無符号整數的編碼,本章其他小節描述了存儲其他類型資料的編碼,下一章将分析存儲器中存儲程式指令的編碼。

3.1.2整數

數字必須以二進制形式表示才能存儲到計算機存儲器中。具體的編碼視這個數字有小數部分還是整數而定。如果是整數,那麼編碼也取決于它永遠是正的還是也可以為負。

無符号二進制(unsigned binary)用于表示永遠為正的整數。在學習二進制之前,我們先複習十進制(decimal或縮寫dec),然後按這個方法學習二進制。

也許因為我們用10根手指計數和加法而發明了十進制,使用這個優雅規制寫的算術書出現在公元8世紀的印度,它被翻譯成阿拉伯文并最終被商人帶到了歐洲,這裡它被從阿拉伯文翻譯成拉丁文。因為那時人們認為它起源于阿拉伯,是以數字被稱為阿拉伯數字,但是印度-阿拉伯數字應該是更準确的名字,因為它實際上起源于印度。

以10為底的阿拉伯數字計數如下(當然是向下讀):

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

從0開始,印度人接着發明了下一個數字1的符号,然後是2,直到符号9。這時,他們看着自己的手想到了一個神奇的點子。在最後一根手指後面,他們沒有發明新的符号,而是用前面兩個符号1和0一起表示下一個數字10。

剩下的故事你都知道了。當到19時,他們看到9是他們創造的符号中最高的符号了,是以他們把它降到0同時把1增加到2,這樣形成20。從29到30,最終99到100,不斷地繼續,都是同樣的處理。

如果我們僅有8個指頭而不是10個将會怎樣呢?到了7,下一個數字用完了最後一根手指,我們不必發明一個新符号,下一個數字會以10來表示。以8為底(八進制,octal或縮寫為oct)計數是這樣的:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

八進制中77的下一個數字是100。

比較十進制和八進制方法,你會注意到八進制的5(oct)和十進制的5(dec)是同樣的數字,但八進制21(oct)和十進制21(dec)是不一樣,反而和十進制17(dec)是一樣的。數字以八進制表示看上去比它們實際上以十進制表示要顯得大一些。

假如我們不是有10個或者8個指頭而是有3個指頭會怎樣呢?規律是一樣的,三進制計數是這樣的:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

最後,我們看看無符号二進制表示。計算機僅有兩根手指,以2為底(二進制,binary,或簡稱bin)計數遵循與八進制和三進制完全相同的方法:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

二進制數看上去比它們實際的值要大很多,二進制數10110(bin)隻是十進制的22(dec)。

3.1.3基本轉換

給定一個二進制數,有幾種方法來确定它對應的十進制數。一種方法是簡單地以二進制和十進制往上數到那個數,這種方法對小的數字非常有效。另一種方法是把二進制數每個為1的位的位置值都加起來。

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

例3.1圖3-2a展示了10110(bin)的位置值,最右邊是1的位置值(稱為最低有效位),每個位置值都兩倍于它前面的那個位置值。圖3-2b展示了得到22(dec)的加法。   □

例3.2無符号二進制類似于我們熟悉的十進制。圖3-3展示了58 036(dec)的位置值。數字58 036代表6個1,3個10,沒有100,8個1000和5個10 000。從最右邊1的位置開始,每個位置值都10倍于它前面的位置值。在二進制中,每個位置值是兩倍于它前面的那個位置值。   □

無符号數值能友善地表示為數制基底的多項式(基底也稱為數制的基數(radix))。圖3-4給出了10110(bin)和58 036(dec)的多項式表示。最低有效位總是基數的0次方,即1。接下來的有效位是基數的一次方,即基數本身。從多項式的結構可以看到每個位置值是前一個位置值乘以基數。

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

在二進制中,隻有1的位置的值是奇數,所有其他位置(2的位置,4的位置,8的位置等)的值都是偶數。如果1的位置的值是0,那麼二進制數的值将是幾個偶數值相加的和,是以一定是偶數。另一方面,如果二進制數的1的位置的值是1,那麼它的值就是把1和幾個偶數值相加,是以一定是奇數。與在十進制中一樣,你可以通過檢測1的位置的數字很容易地确定一個二進制數是奇數還是偶數。

确定十進制數等值的二進制數有點兒棘手。一種方法是連續地把這個數除以2,保留餘數的記錄,餘數的逆序就是這個二進制數。

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

例3.3圖3-5把22(dec)轉換成二進制。22除以2等于11,餘數為0,把餘數寫在右列,接着11除以2等于5餘1。繼續進行直到商為0,這樣形成一個餘數列,從下往上讀取餘數就形成二進制數10110。    □

注意:最低有效位是用原始數字除以2得到的餘數,這與僅通過檢測最低有效位确定一個二進制數是奇數還是偶數是一緻的。如果原始數是偶數,除以2将得到餘數0,這個0将是最低有效位。相反,如果原始數是奇數,最低有效位将是1。

3.1.4無符号整數的範圍

所有這些基于阿拉伯數字的計數方法都可以表示任意大的數字。然而,一個真實的計算機中每個單元的位數是有限的。圖3-6展示了一個7位的單元是如何存儲數22(dec)的。注意開頭的兩個0,它們不影響數值,但是對于指定存儲器位置的内容是必需的。對于7位的計算機來說,不帶方框,這個數應該寫作

001 0110

開頭的兩個0仍然是必須要有的。本書在顯示位串時,從右開始每4位一組,組間有一個空格(為了易讀)。

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

無符号數值的範圍取決于一個單元的位數。一個全0的序列代表最小的無符号值,全1的序列代表最大的。

例3.4一個7位的單元可以存儲的最小無符号整數是

000 0000(bin)

可以存儲的最大無符号整數是

111 1111(bin)

最小的是0(dec),最大的是127(dec)。一個7位單元不能存儲大于127的無符号整數。□

3.1.5無符号加法

無符号二進制數加法和無符号十進制加法一樣,隻不過更容易,因為隻需學習2位加法法則而不是10個數字的加法法則。位加法法則是

0+0=0

0+1=1

1+0=1

1+1=10

我們熟悉的十進制中的進位技術也一樣在二進制中适用。如果一列中的兩個數相加大于1,那麼必須進1到下一列。

例3.5假設有一個6位的單元,把01 1010和01 0001兩個數相加,簡單地從最低有效位列開始把一個數寫在另一個上面:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

注意當到達從右數的第5列時,1+1等于10,必須寫0并進1到下一列,在最後一列1+0+0得出和中最左邊的1。

為了驗證這個進位技術對二進制有效,把這兩個數與它們的和都轉換為十進制數:

01 1010(bin)=26(dec)

01 0001(bin)=17(dec)

01 1011(bin)=43(dec)

毫無疑問,在十進制中,26+17=43。    □

例3.6這些例子顯示了進位可以沿着連續的列傳遞:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

在第二個例子中,當到達從右數的第四列時,有一個來自前一列的進位,那麼1 + 1 + 1等于11,必須寫1并進1到下一列。 □

3.1.6 進位位

前面例子中的6位單元的表數範圍是00 0000到11 1111(bin),或0到63(dec)。兩個加數在表數範圍内,而和不在是有可能的,這時和就太大了而不能裝進6位的存儲單元。

為了标記出這種情況,cpu有一個特殊的位稱為進位位(carry bit),以字母c表示。當兩個二進制數相加時,如果最左列(最高有效位)的和産生了一個進位,那麼c被設定為1,否則c為0。換句話說,c總是包含單元最左列産生的進位。在前面所有的例子中,和都在表數範圍内,是以進位位為0。

例3.7這裡有兩個展示進位位影響的例子:

《計算機系統:核心概念及軟硬體實作(原書第4版)》——3.1 無符号二進制表示

在第二個例子中,cpu進行42 + 26的運算,正确的結果是68,但它太大不能裝進6位的單元中。注意6位單元的表數範圍是0到63,是以隻能存儲最右的6位,得到不正确的結果4,而進位位也被設定為1,表示最左一列有進位。        □

計算機對兩個二進制數的減法是通過加上第二個數的負數來實作的。例如,要計算減法42-26,計算機會計算加法42+(-26)。因為沒有辦法存儲負數,是以不可能用無符号表示兩個整數的減法運算。下一節将描述存儲負數的表示法。用這種表示法,c位是加上第二個數的負數的進位。