簡介:為什麼數系如此重要?

歡迎來到電腦科學數據表示的世界!這一章起初看起來可能像是純數學,但它卻是電腦運作最根本的基礎。為什麼呢?因為電腦並不使用英語或十進位(Base 10);它們使用的是二進位(Binary,Base 2)——由 0 和 1 組成的序列。

理解數系與進位轉換,能讓你清楚看到數據如何在處理器內部被儲存、處理和表示。這些知識對於後續學習組合語言、浮點數以及數據儲存計算等課題至關重要。


1. 核心數系 (3.5.1)

1.1 十進位 (Decimal, Base 10) – 我們日常使用的系統

我們每天都在使用十進位系統。它被稱為 Base 10,是因為它使用了 10 個獨特的數字(0 到 9)。

  • 基數 (Base): 10
  • 所用數字: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

我們透過位值表示法 (Positional Notation) 來理解數值,即數字所在的位置決定了它代表 10 的幾次方。
例子:十進位數 459 實際上是:

$$4 \times 10^2 + 5 \times 10^1 + 9 \times 10^0$$

1.2 二進位 (Binary, Base 2) – 電腦的語言

電腦使用二進位,因為電子電路只能表示兩種狀態:開 (ON, 1) 或 關 (OFF, 0)。每一個 1 或 0 被稱為一個位元 (Bit,Binary Digit)

  • 基數 (Base): 2
  • 所用數字: 0, 1

二進位同樣使用位值表示法,但基於 2 的冪次。
例子:一個 8 位元的二進位數字使用以下的欄位權重:

$$128, 64, 32, 16, 8, 4, 2, 1$$

1.3 十六進位 (Hexadecimal, Base 16) – 程式設計師的捷徑

二進位字串(例如 110101100101)通常會變得非常長,人類難以閱讀和記憶。十六進位 (Hex) 是二進位的便利簡寫。

  • 基數 (Base): 16
  • 所用數字: 0-9 以及 A-F

十六進位使用 16 個獨特的符號。由於我們只有 10 個數字,因此使用字母 A 到 F 來表示 10 到 15 的數值。

十進位二進位 (4 bits)十六進位
000000
910019
101010A
151111F

2. 數系轉換 (3.5.1)

你必須能夠在所有三種進位制之間轉換:十進位 (Base 10)、二進位 (Base 2) 和十六進位 (Base 16)。

2.1 二進位轉十進位 (Base 2 轉 Base 10)

這是最簡單的轉換:將每個數字乘以其對應的 2 的冪次,然後將結果相加。

逐步範例:將 \(101101_2\) 轉換為十進位。

  1. 寫出位值欄位標題(2 的冪次,從右邊開始,\(2^0 = 1\))。
  2. 將二進位數字填入標題下方。
  3. 將出現 '1' 的欄位數值相加。
$2^5 (32)$$2^4 (16)$$2^3 (8)$$2^2 (4)$$2^1 (2)$$2^0 (1)$
101101

$$32 + 0 + 8 + 4 + 0 + 1 = 45$$

結果:\(101101_2 = 45_{10}\)

2.2 十進位轉二進位 (Base 10 轉 Base 2)

對於較大的數字,最可靠的方法是重複除以 2 法 (Repeated Division by 2),並將餘數按相反順序排列。

逐步範例:將 \(45_{10}\) 轉換為二進位。

  1. 將十進位數除以 2。
  2. 記錄餘數(0 或 1)。
  3. 將商數重複此過程,直到商數為 0。
  4. 由下(最高有效位 MSB)至上(最低有效位 LSB)讀取餘數。
除法商數餘數 (Bit)
$45 \div 2$221
$22 \div 2$110
$11 \div 2$51
$5 \div 2$21
$2 \div 2$10
$1 \div 2$01

由下向上讀取:101101。
結果:\(45_{10} = 101101_2\)

轉換要點:二進位和十六進位的轉換對於表示數據的內部結構(如記憶體位址或指令代碼)至關重要。

2.3 二進位與十六進位之間的轉換

這種轉換非常直接且簡單,因為 \(16 = 2^4\)。一個十六進位數字剛好可以完全表示四個二進位位元。

二進位轉十六進位:四位一組

從右邊(LSB)開始,將二進位數字每四個分成一組。將每組轉換為對應的單一十六進位數字。

範例:將 \(1101011011_2\) 轉換為十六進位。

  1. 在左側補零以組成四位一組:0011 0101 1011
  2. 轉換每組:
    • $0011_2 = 3_{16}$
    • $0101_2 = 5_{16}$
    • $1011_2 = B_{16}$(因為 \(11_{10} = B_{16}\))
  3. 合併:35B

結果:\(1101011011_2 = 35B_{16}\)

十六進位轉二進位:展開每個數字

將每個十六進位數字轉換為對應的 4 位元二進位序列。

範例:將 \(E7_{16}\) 轉換為二進位。

  1. 轉換 E:$E_{16} = 14_{10} = 1110_2$
  2. 轉換 7:$7_{16} = 7_{10} = 0111_2$
  3. 合併:11100111

結果:\(E7_{16} = 11100111_2\)

快速回顧:轉換技巧

二進位 $\leftrightarrow$ 十六進位:務必使用 4 位元分組快捷法。這既快速又不容易出錯。

十進位轉二進位:使用重複除以 2 法,並由下往上讀取餘數。

二進位轉十進位:寫出 2 的冪次(128, 64, 32, 16, 8, 4, 2, 1)並將「1」對應位置的數值相加。


3. 資訊單位 (3.5.2)

3.1 位元與位元組 (Bits and Bytes)

最小的資訊單位是位元 (bit, b)。一個位元儲存一個 0 或 1。

電腦記憶體和儲存裝置中使用的基本單位是位元組 (byte, B)

  • 一個位元組是由 8 個位元組成的。
  • 一個位元組可以表示 \(2^8 = 256\) 種不同的數值(從 0 到 255)。

3.2 \(2^n\) 規則

如果你有 \(n\) 個位元,總共可以表示 \(2^n\) 種不同的數值。

你知道嗎?電腦系統中可定址的記憶體大小也取決於位址匯流排 (Address Bus) 的位元數(例如,32 位元位址匯流排可以存取 \(2^{32}\) 個位置)。

例子:

  • 2 個位元可以表示 \(2^2 = 4\) 個值(00, 01, 10, 11)。
  • 3 個位元可以表示 \(2^3 = 8\) 個值(000 到 111)。
  • 16 個位元可以表示 \(2^{16} = 65,536\) 個值。

3.3 十進位與二進位前綴

當討論儲存量(KB, MB 等)時,有兩種系統,分別基於 10 的冪次或 2 的冪次。區分標準十進位前綴(kilo, mega)與二進位前綴(kibi, mebi)非常重要。

十進位前綴(10 的冪次)

這些是數學和大多數儲存裝置製造商(如硬碟)所使用的標準單位。

名稱符號10 的冪次近似值
kilok$10^3$1,000
megaM$10^6$1,000,000
gigaG$10^9$1,000,000,000
teraT$10^{12}$$10^{12}$

例子:1 kB (kilobyte) = \(10^3\) bytes (1,000 bytes)

二進位前綴(2 的冪次)

這些前綴由電腦系統用於指代記憶體和數據大小,因為所有內容都基於 2 的冪次。標準二進位前綴在中間加上了 "bi"(kibi, mebi, gibi, tebi)。

名稱符號2 的冪次精確值
kibiKi$2^{10}$1,024
mebiMi$2^{20}$1,048,576
gibiGi$2^{30}$$2^{30}$
tebiTi$2^{40}$$2^{40}$

例子:1 KiB (kibibyte) = \(2^{10}\) bytes (1,024 bytes)

類比:可以將其想像為測量長度。十進位的 kilo 正好是 1000 米;而二進位的 kibi 稍微長一點,是 1024 米。


4. 二進位整數表示 (3.5.3)

4.1 無號二進位 (Unsigned Binary, 3.5.3.1)

無號二進位用於表示正整數(以及零)。「無號」意指沒有專門的位元來指示數字是正還是負。

  • 所有位元都用於表示數字的大小(數值)。
  • 最小值始終為 0。
  • 對於 \(n\) 個位元,最大值為 \(2^n - 1\)。

例子:在 8 位元無號二進位中,範圍是 0 到 \(2^8 - 1\)(即 0 到 255)。

4.2 無號二進位算術 (3.5.3.2)

二進位加法

二進位加法的規則很簡單,就像十進位加法一樣,但當總和達到 2 時就會進位。

$A$$B$進位 (Carry)
0000
0110
1010
1101 (進位 1)
1 + 1 + 進位 111 (進位 1)

範例:在 4 位元中計算 \(5_{10} + 3_{10}\)

   1  1  0  0 <-- 進位
     0  1  0  1  (5)
+    0  0  1  1  (3)
-----------------
     1  0  0  0  (8)
處理溢位 (Overflow)

如果加法的結果超過了分配位元數的最大範圍,就會發生溢位 (overflow)。這個多出來的位元會丟失,導致結果錯誤。
例子:在 4 位元無號二進位中計算 \(15 + 1\):

     1  1  1  1  (15)
+    0  0  0  1  (1)
-----------------
(1)  0  0  0  0  (0 - 錯誤!)

第 5 個位元(1)是溢位並被丟棄,這意味著 \(15 + 1\) 看起來等於 0。

二進位乘法

二進位乘法使用簡單的移位和加法,類似於十進位的長乘法,但我們只需要乘以 0 或 1。

範例:\(101_2 \times 11_2\) (\(5 \times 3\))

      1 0 1
    x 0 1 1
    -------
      1 0 1 (101 x 1)
+  1 0 1 0 (101 x 1 左移)
    -------
   1 1 1 1  (15)

結果:\(1111_2 = 15_{10}\)

🛑 常見錯誤提醒 (算術)

務必記住二進位加法中的進位位元!如果你在固定的位元數(如 8 位元)下運算,任何超出最後一個位置的進位都是溢位 (overflow)

4.3 使用二補數 (Two's Complement) 表示有號二進位 (3.5.3.3)

為了表示負數,我們使用有號二進位。此課程大綱中你唯一需要掌握的方法是二補數 (Two's Complement)

在二補數中,最高有效位 (MSB)(最左邊的位元)作為符號指示器:

  • 若 MSB 為 0,該數為正數。
  • 若 MSB 為 1,該數為負數。
將正十進位轉換為二補數

這與轉換為無號二進位相同,但如果你在特定的位元長度(例如 8 位元)下工作,必須確保開頭有 0。

例子:8 位元的 +13 表示為 \(00001101_2\)。

將負十進位轉換為二補數

遵循「反轉並加 1 (Flip and Add 1)」法則:

  1. 找出該數的正數二進位表示(例如,對於 -13,使用 +13)。
  2. 反轉 (Flip) 所有位元(0 變 1,1 變 0)。這稱為一補數 (One's Complement)
  3. 對反轉後的結果加 1

逐步範例:將 \(-13_{10}\) 轉換為 8 位元二補數。

  1. 正 13:\(00001101\)
  2. 反轉位元(一補數):\(11110010\)
  3. 加 1:
        11110010
    +          1
        --------
        11110011
            

結果:\(-13_{10} = 11110011_2\)。(請注意 MSB 為 1,確認其為負數)。

將二補數轉換回十進位

若 MSB 為 0,按正常方式轉換(它是正數)。

若 MSB 為 1(它是負數),可以使用捷徑:將 MSB 當作負權重,其餘部分正常加總。

範例:將 \(11110011_2\) 轉換回十進位 (8 位元)。

$-2^7 (-128)$$2^6 (64)$$2^5 (32)$$2^4 (16)$$2^3 (8)$$2^2 (4)$$2^1 (2)$$2^0 (1)$
11110011

$$(-128) + 64 + 32 + 16 + 0 + 0 + 2 + 1 = -13$$

二補數減法

在電腦算術中,減法 (A - B) 是通過加上 B 的負數來執行的:$$A - B = A + (-B)$$

逐步範例:在 8 位元中計算 \(25_{10} - 10_{10}\)。

我們執行 \(25 + (-10)\)。

  1. 正 25:\(00011001\)
  2. 負 10 (\(-10_{10}\)):
    • 正 10:00001010
    • 反轉:11110101
    • 加 1:11110110
  3. 將這兩個二進位數相加:
      1 1 1 1 1 0 0 0 <-- 進位
        0 0 0 1 1 0 0 1  (25)
    +   1 1 1 1 0 1 1 0  (-10)
    ------------------
    (1) 0 0 0 0 1 1 1 1  (15)
            

最後的進位(括號內)在二補數算術中會被丟棄。剩餘的 8 位元 \(00001111_2\) 轉換為 \(15_{10}\)。

結果:減法成功通過加法完成。

二補數中 \(n\) 位元的範圍

由於一個位元專用於符號,因此最大範圍比無號二進位小。

對於 \(n\) 個位元,範圍是:

$$\text{最小值:} -2^{n-1}$$ $$\text{最大值:} +2^{n-1} - 1$$

例子:對於 8 位元 (\(n=8\)):

  • 最小值:$-2^{(8-1)} = -2^7 = -128$
  • 最大值:$2^{(8-1)} - 1 = 2^7 - 1 = 127$

重點總結:二進位表示

選擇無號 (Unsigned)有號 (二補數, Signed) 決定了你可以儲存的數字範圍。無號提供了更大的正數範圍(例如 8 位元中 0 到 255),而二補數則允許你同時儲存正整數和負整數(例如 8 位元中 -128 到 127)。