二進位編碼數字

二進位編碼數字

二進位編碼數字,即計算機編碼,指電腦內部代表字母或數字的方式。

編碼介紹


位元、位元組、字組位元和無號整數
計算機的基本儲存單位是“位元”,通過開關變化設置表達值0或1。在有兩個位元的情況下可以得到四個不同的狀態:
如果有三個位,則有八種狀態:
每當增加一個位時,將得到兩倍的狀態。
計算機使用不同數量的位元儲存不同種類的信息。4個位元被稱為一“nybble”,8個被稱為一位元組,也有16,32,或更多位元組成的信息計量單位。
一個nybble可以為16種不同的情況編碼,例如數字0到15。大體上,使用任何序列的排列來表示不同的16種狀態是可以的,但在實際的應用通常是這樣的:
這樣的表示是很自然的,因為它符合我們所熟悉的十進位數表示方法。例如,給定一個十進位數:
• 7531
我們很自然地把它理解為:
• 7 × 1000 + 5 × 100 + 3 × 10 + 1 × 1
或者,使用10的冪來表示:
• 7 × 103+ 5 × 102+ 3 × 101+ 1 × 100
注意任何數(除了0)的0次冪都是1。
數據中的每個數字錶示從0到9的值,這樣我們有10個不同的數字,那就是我們把它稱為“十進位”的原因。每個數字可以通過10的某次冪來決定它的位置。這聽起來很複雜,但實際上並不是這樣的。這正是當您讀一個數字的使用認為是理所當然的事情,您甚至都不用仔細思考它。
類似地,使用二進位編碼就像上面所說的那樣,值13是這樣編碼的:
1101
每一個位置有兩個數字可以選擇,所以我們稱它為“二進位”。因此,它們的位置是這樣決定的:
1101 =1 × 8 + 1 × 4 + 0 × 2 + 1 × 1 = 13(十進位)
八進位和十六進位數
我們討論一些偏外的話題:對二進位數字的表示方法。計算機通常使用二進位來表達數據,但是在實際中如果使用像這樣的二進位:
1001 0011 0101 0001
那將是一件痛苦的事,並且很容易出錯。通常計算機使用一個基於二進位的表達方式:八進位,或更通常使用的,十六進位。
這一件聽起來挺狡猾但實際上又很簡單的事。如果不是這樣的話,我們就不會這樣使用了。在平常的十進位體系中,我們有10數字(0到9)按以下方式構成排列:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
在八進位中,我們只有八個數字(0到7)按以下方式構成排列:
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 ...
也即是說,八進位的“10”相當於十進位的“8”,八進位的“20”相當於十進位的“16”,以此類推。
在十六進位中,我們只有十六個數字(0到9,然後是從a到f)按以下方式構成排列:
0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 ...
也即是說,十六進位的“10”相當於十進位的“16”,十六進位的“20”相當於十進位的“32”。
有符號整數和補碼
在定義了無符號二進位數后,我們就要著手定義負數了,或稱為“有符號整數”。最簡單的一個方法是保留一個位來表示數值的符號。這個“符號位”可以位於數值的最左邊,當然也可以位於數值的最右邊。如果這個符號位為0,表示數值是正的,如果這個符號位為1,表示數值是負的。
這樣做是可以的,雖然從人類的角度來看是最明顯的解決方案,但是它對於計算機來說有可能帶來一些難度。例如,這種編碼使得0可以有正負兩種。人們可能對此感到不可思議,但是這對計算機來說是適應的。
對計算機來說,更自然的表達方式是對給定的位數的二進位數按其範圍分成兩半,其中前一半用來表示負數。例如,在4位數值中,你可以得到:
我們得到了一個“有符號整數”數字系統,使用所知道的,為了一些不是很重要的原因,“補碼”編碼方式。對16位有符號數字編碼來說,我們可以得到範圍為-32,768到32,767的有符號數字。對一個32位的有符號編碼系統來說,我們可以為從-2,147,483,648到2,147,483,647的數編碼。
與只改變符號位來表示負數的編碼方式相比,“補碼”編碼方式與之有所不同。例如對於-5來說,只對符號位編碼,應該是:
但是對於“補碼”編碼方式來說,則是:
這對於符號編碼來說是-3。關於為什麼計算機要使用補碼這種編碼方式我們會在後面解釋。
所以,我們可以以二進位方式來表示正負兩種不同的數值。請記住對於一個二進位數來說,只有兩種解釋方式。如果在內存中有一個這樣的二進位數值:
定點小數
這種格式通常被用於商業計算(例如在電子表格或COBOL中);因為在這裡,丟棄小數位來記錄金錢是不能接受的。因此了解二進位如何存貯小數是十分有用的。
首先去我們必須決定要用多少位來存貯小數部分和多少位來存儲整數部分。假設我們使用32位來表示這種格式,那麼我們用16位表示整數部分,16位來表示小數部分。
小數部分怎麼使用呢?這沿用了表示整數的方式:如果8位接下來是4位,是2位,1位,那麼當然接下來就是半位,1/4位和1/8位等等了。
例如:
有一點棘手的是,如果您要表達1/5(十進位的0.2),那您不能得到精確的數值表達方式。最好的方法只能是:
13107/65536 = 00000000 00000000.00110011 00110011 = 0.1999969... 十進位
13108/65536 = 00000000 00000000.00110011 00110100 = 0.2000122... 十進位
然而不,您不能這樣做,即使您有更多的數位來表達。問題是,一些小數使用二進位的方式不能精確地表達出來。除非您使用一個特殊的辦法。這個特殊的辦法是分別使用兩個數字來表達小數:一個是分子,一個是分母。然後您可以使用學校學習的加、減、乘、除來得到它們。然而,這些方法不能表達更高級的數字(例如平方根),或者如果這兩個分母的最小公倍數很大的話,那就難以使用。這就是使用定點小數表達小數的缺點。
浮點小數
當我們使用了有符號和無符號的數值表達方式時。如果遇到連32位也不足以表達的大範圍的數,或也許可以表達,但我們必須為此放棄小數位時,我們可以選擇的以獲得更大範圍的數值的表達方式的方法是使用“浮點小數”格式而拋棄“定點小數”格式。
編程語言中的數
對於低級語言的編程者來說,他們要擔心有符號和無符號、定點和浮點數的運算。他們必須使用十分不同的代碼來實現操作。
但是,對高級語言的編程者來說,諸如LISP和Python提供了一些列諸如“有理數”、“複數”之類的抽象數據類型。而他們可以斷言他們的系統可以使用數學操作做正確的運算。由於操作符重載,數學運算可以應用於任何數字——無論是有符號的、無符號的、有理數、定點小數、浮點小數或複數。
文本編碼:ASCII和字元串
我們已經得到不同的方法來存儲數據了,那麼文本呢?我們怎麼存儲姓名、地址或寫給朋友的信件呢?
當然,如果您還記得位是位的話,我們沒有理由不能使用位來表達字母“A”或“?”或“Z”之類的。因為很多計算機每次處理一個位元組,所以使用單位元組的數據來表達單個字母會很方便。我們可以使用這個:
來表示字母“F”。計算機使用這樣的“字元編碼”來向顯示程序傳送要求的文本。
下面是一個用來存儲西方字母的標準二進位編碼,就是通常所說的“美國信息交換標準碼”(英文簡稱“ASCII”),下面的編碼為ASCII編碼,使用“d”表示十進位編碼,“h”表示十六進位代碼,“o”表示八進位代碼:
上面這個列表的最左邊有一個些奇怪的字元,例如“FF”和“BS”,這些都不是文本字元。相反,它們是控制字元,也就是說當這些字元發送到特定的設備時,它將產生一些動作。例如“FF”表示換頁,或彈出;“BS”表示退格,而“BEL”表示一個響聲。在一個文本編輯器中,它們會顯示成一個白色或黑色的方塊,或笑臉、音符或其它一些奇怪的符號。要打出這些字元,可以使用CTRL鍵和一個合適的代碼。例如同時按住“CTRL”和“G”,或簡寫成“CTRL-G”或“^G”可以打出一個BEL字元。
上面這個ASCII碼錶示定義了128個字元,這意味著ASCII碼只需要7位。但是,很多計算機都以位元組為單位存儲信息。這個額外的一位可以定義第二個128個字集,一個“擴展”字集。
在實際中,有很多不同的“擴展”字集,提供很多例如數學符號等的符號或非英語字元。這個擴展字集並沒有進行標準化,並經常會引起混淆。
這個表格強調了這篇文章的主題:位就是位。這樣的話,您可以使用位來表示字元。您可以把特殊的代碼描述成特殊的十進位、八進位和十六進位,但是它們仍然是相同的代碼。這些數值的表達,無論是十進位、八進位或十六進位,都只是相同的位的表達。
當然,您可能在一段話中表達很多的字元,例如:
Tiger, tiger burning bright!
這只是簡單的替換成ASCII碼,表示成:
54 69 67 65 72 2c 20 74 69 67 65 72 20 62 75 ...
計算機把這種ASCII“字元串”以連續空間的“數組”來存儲。一些應用程序可以包括一個二進位數值表示字元串的長度,但是更通常的做法是使用一個表示結尾的字元NULL(ASCII表中的0字元〕表示字元串的結束。
參見
• 二進位
• 二進位數學
• 二進位編碼數據
• 八進位
• 十六進位