學程式、上資訊課或調整網頁顏色時,一定會遇到二進位和十六進位。很多人背得出「255 就是 FF」,卻說不出為什麼。這篇文章從進位制的觀念講起,帶你用紙筆完成各種換算,每個例子都可以自己驗算。想直接對答案的話,可以打開進位轉換器,輸入任何一種進位,其他進位會即時算出來。
什麼是進位制?
進位制是「數到多少就進一位」的規則。十進位有 0 到 9 共十個數字,數到 10 就進位,所以每一位代表 10 的次方:
345 = 3×100 + 4×10 + 5×1
把「10」換成別的數字,就得到其他進位:
| 進位 | 可用的數字 | 每一位代表 |
|---|---|---|
| 二進位 | 0、1 | 2 的次方(1、2、4、8、16…) |
| 八進位 | 0 到 7 | 8 的次方(1、8、64、512…) |
| 十進位 | 0 到 9 | 10 的次方(1、10、100…) |
| 十六進位 | 0 到 9、A 到 F | 16 的次方(1、16、256、4096…) |
十六進位需要 16 個符號,數字不夠用,所以借用英文字母:A=10、B=11、C=12、D=13、E=14、F=15。
同一個數量可以用不同進位寫出來。十進位的 255 寫成二進位是 11111111、八進位是 377、十六進位是 FF,它們代表的是同一個數。
為什麼電腦用二進位?
電腦是由電路組成的,而電路最容易穩定分辨的就是兩種狀態:有電與沒電、高電位與低電位。把這兩種狀態對應成 1 和 0,就是二進位。如果要讓電路分辨十種不同的電壓,只要有一點雜訊就可能判斷錯誤;只分兩種則可靠得多。
一個 0 或 1 稱為一個位元(bit),8 個位元組成一個位元組(byte)。一個位元組有 2 的 8 次方,也就是 256 種組合,剛好可以表示 0 到 255。
十六進位為什麼這麼常用?
二進位對電腦很方便,對人卻很難讀:11010110 一眼很難看出是多少,抄寫時也容易漏掉一位。十六進位剛好解決這個問題,因為 16=2 的 4 次方,一個十六進位數字恰好等於 4 個位元:
1101 0110
D 6 → D6
一個位元組(8 個位元)就能寫成兩個十六進位數字,既短又能一對一還原成二進位。常見的例子有:
- 網頁色碼:
#FF8800拆成 FF、88、00,分別是紅 255、綠 136、藍 0,每種顏色剛好占一個位元組。 - 記憶體位址:像
0x7FFF這樣的寫法,前面的0x表示後面是十六進位,7FFF 等於十進位的 32767。 - MAC 位址與雜湊值:也都是用十六進位把一長串位元寫得比較短。
八進位則是每 3 個位元換成一個數字,現在最常看到的地方是 Linux 的檔案權限(例如 755)。
十進位轉二進位:短除法
把數字一直除以 2,記下每次的餘數,直到商變成 0,最後把餘數由下往上讀。以 156 為例:
156 ÷ 2 = 78 … 餘 0
78 ÷ 2 = 39 … 餘 0
39 ÷ 2 = 19 … 餘 1
19 ÷ 2 = 9 … 餘 1
9 ÷ 2 = 4 … 餘 1
4 ÷ 2 = 2 … 餘 0
2 ÷ 2 = 1 … 餘 0
1 ÷ 2 = 0 … 餘 1
由下往上讀餘數:1、0、0、1、1、1、0、0,所以 156 的二進位是 10011100。
同樣的方法換成除以 8 或除以 16,就能轉成八進位或十六進位。例如 156÷16=9 餘 12,9÷16=0 餘 9,12 寫成 C,由下往上讀是 9C。
二進位轉十進位:位值展開
反過來,把每一位乘上它代表的 2 的次方,再全部加起來。最右邊是 2⁰=1,往左依序是 2、4、8、16、32、64、128:
10011100
= 1×128 + 0×64 + 0×32 + 1×16 + 1×8 + 1×4 + 0×2 + 0×1
= 128 + 16 + 8 + 4
= 156
結果回到 156,和前面的短除法互相驗證。十六進位也是一樣的做法,只是改成乘 16 的次方:
2F = 2×16 + 15×1 = 32 + 15 = 47
二進位、八進位、十六進位互轉:分組就好
因為 8 和 16 都是 2 的次方,這三種進位之間不需要經過十進位,直接分組即可。記得一律從最右邊開始分,左邊不夠的補 0。
以 11010110 為例:
- 每 4 位一組:
1101 0110→ D、6 → 十六進位 D6 - 每 3 位一組:
011 010 110→ 3、2、6 → 八進位 326
驗算:D6=13×16+6=214;326=3×64+2×8+6=192+16+6=214,兩者一致。
小數怎麼換算?
整數部分用「除以 2 取餘數」,小數部分則相反,用「乘以 2 取整數部分」,而且是由上往下讀。以 0.625 為例:
0.625 × 2 = 1.25 → 取 1,剩 0.25
0.25 × 2 = 0.5 → 取 0,剩 0.5
0.5 × 2 = 1.0 → 取 1,剩 0(結束)
所以 0.625=0.101(二進位)。驗算:1×½+0×¼+1×⅛=0.5+0.125=0.625。再加上整數部分 10=1010,就得到 10.625=1010.101,寫成八進位是 12.5、十六進位是 A.A。
不過並不是每個小數都乘得完。0.1 乘以 2 會一直循環下去,得到 0.000110011001…,永遠寫不完。這就是為什麼很多程式語言裡 0.1+0.2 不會剛好等於 0.3。進位轉換器遇到這種情況時,小數最多顯示 32 位,並在旁邊註明「已截斷」。
二補數:電腦怎麼表示負數?
在紙上寫負數只要加個負號,例如 -255=-11111111。但電腦裡只有 0 和 1,沒有「負號」這個符號,所以大多數電腦採用二補數。
做法是先決定位元寬度(例如 8 位元),然後:
- 寫出正數的二進位,不足的位數在左邊補 0。
- 把每個位元反轉(0 變 1、1 變 0)。
- 再加 1。
以 8 位元的 -5 為例:
5 的二進位:00000101
全部反轉: 11111010
加 1: 11111011 ← 這就是 -5
可以驗算:5+(-5) 應該等於 0。00000101+11111011=1 00000000,超出 8 位元的那個 1 被丟掉,剩下 00000000,剛好是 0。這也是二補數的優點——加法和減法可以共用同一套電路。
幾個值得記住的 8 位元數值:
| 十進位 | 8 位元二補數 |
|---|---|
| 127(最大值) | 01111111 |
| 1 | 00000001 |
| 0 | 00000000 |
| -1 | 11111111 |
| -128(最小值) | 10000000 |
最左邊的位元是 0 代表非負數,是 1 代表負數。8 位元能表示 -128 到 127;16 位元是 -32768 到 32767;32 位元是 -2147483648 到 2147483647。
要注意的是,同一串位元怎麼解讀取決於「有沒有正負號」:11111111 當成無號數是 255,當成 8 位元二補數則是 -1。
小結
- 進位制就是「每一位代表某個數的次方」,二進位是 2、十六進位是 16。
- 電腦用二進位,是因為電路最容易可靠地分辨兩種狀態。
- 一個十六進位數字等於 4 個位元,所以色碼、記憶體位址都用十六進位書寫。
- 十進位轉其他進位用短除法(餘數由下往上讀),轉回來用位值展開。
- 二進位、八進位、十六進位互轉只要從右邊分組。
- 負數在電腦裡用二補數表示:位元反轉再加 1。
練習時可以先自己用紙筆算一次,再把數字輸入進位轉換器核對。工具會列出除以 2 取餘數的每一步、位值展開式,以及 8、16、32 位元的二補數,很適合拿來對照自己的計算過程。