Stories

Detail Return Return

有符號整數的三種編碼方式:原碼、反碼和補碼 - Stories Detail

在計算機中,原碼、反碼、補碼 是用於表示有符號整數的三種編碼方式,主要用於解決二進制數的 正負表示加減運算 問題。它們的核心區別在於 符號位的處理負數的表示方法


原碼(Sign-Magnitude)

定義

  • 最高位(最左邊的一位)表示符號:
    • 0 表示正數(如 +5
    • 1 表示負數(如 -5
  • 其餘位表示數值的絕對值。

示例(8位二進制)

十進制 原碼錶示(8位)
+5 0000 0101
-5 1000 0101

特點

直觀:和人類書寫習慣一致(正負號+數值)。
問題

  1. +0-0 不唯一
    • +0 = 0000 0000
    • -0 = 1000 0000(計算機無法區分)
  2. 加減運算複雜
    • 需要額外判斷符號位,硬件實現麻煩。

反碼(Ones' Complement)

定義

  • 正數:和原碼相同。
  • 負數:在原碼基礎上,符號位不變,數值位取反0110)。

示例(8位二進制)

十進制 反碼錶示(8位)
+5 0000 0101
-5 1111 1010
十進制運算 反碼計算 反碼計算結果(十進制)
1 +(-1)= 0 [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 -0
1 +(-2)= -1 [0000 0001]反 + [1111 1101]反 = [1111 1110]反 = [1000 0001]原 -1
-1 +(2)= 1 [1111 1110]反 + [0000 0010]反 = [0000 0000]反(溢出) = [0000 0000]原 0(溢出歸0

從上表可以看出,如果用反碼直接進行計算,雖然有所改善,但仍有問題,所以計算機中的運算也不能直接用反碼。

特點

仍然存在 +0-0 問題

  • +0 = 0000 0000
  • -0 = 1111 1111(仍然無意義)

運算仍需調整

  • 加減法後可能需要 “循環進位”(如 1 + (-1) = 0000 0001 + 1111 1110 = 1111 1111-0),需要額外加 1 修正)。

補碼(Two's Complement)⭐(現代計算機標準)

定義

  • 正數:和原碼相同。
  • 負數:在反碼基礎上 +1(即 原碼取反 + 1)。

示例(8位二進制)

十進制 補碼錶示(8位)
+5 0000 0101
-5 1111 1011

計算 -5 的補碼

  1. +5 原碼 = 0000 0101
  2. 取反 = 1111 1010(反碼)
  3. +1 = 1111 1011(補碼)

舉個例子,如果是8位的二進制數:

[+1] = [0000 0001]原 = [0000 0001]反 = [0000 0001]補

[-1] = [1000 0001]原 = [1111 1110]反 = [1111 1111]補

[-2] = [1000 0010]原 = [1111 1101]反 = [1111 1110]補

十進制運算 補碼計算 補碼計算結果(十進制)
1 +(-1)= 0 [0000 0001]補 + [1111 1111]補 = [0000 0000]補 = [0000 0000]原 0(溢出位捨棄
1 +(-2)= -1 [0000 0001]補 + [1111 1110]補 = [1111 1111]補 = [1111 1110]反 = [1000 0001]原 -1
-1 +(2)= 1 [1111 1111]補 + [0000 0010]補 = [0000 0001]補 = [0000 0001]原 1(溢出位捨棄

從上表可以看出,如果使用補碼進行計算,就可以正常的進行加法算術運算了。

特點

解決所有問題

  1. +0-0 統一

    • +0 = 0000 0000
    • -0 :原碼 1000 0000 → 反碼 1111 1111 → 補碼 0000 0000(和 +0 相同)。
  2. 加減法直接運算

    • 5 + (-3) = 0000 0101 + 1111 1101 = 0000 00102,正確)。
  3. 表示範圍更大

    • 8位補碼範圍:-1281000 0000)~ +1270111 1111),比原碼/反碼多一個數(-128)。

那麼至此,總結兩個非常重要的結論:

  1. 正數的原碼反碼補碼是一致的,負數的反碼是原碼除符號位取反,補碼是反碼+1。
  2. 計算機中有符號整數的存儲方式都是以補碼的形式存儲的,運算也是以補碼的形式計算的。

三種編碼對比(8位二進制)

十進制 原碼 反碼 補碼
+5 0000 0101 0000 0101 0000 0101
-5 1000 0101 1111 1010 1111 1011
+0 0000 0000 0000 0000 0000 0000
-0 1000 0000 1111 1111 0000 0000
-128 無法表示 無法表示 1000 0000

為什麼計算機使用補碼

  1. 統一 +0-0,避免歧義。
  2. 加減法可以直接運算,無需額外判斷符號。
  3. 硬件實現簡單,CPU 只需加法器,無需額外電路。
  4. 表示範圍更大(如 8 位補碼可表示 -128~127,而原碼/反碼只能 -127~127)。

常見問題

補碼 1000 0000 代表多少

  • 在 8 位補碼中,1000 0000 表示 -128(沒有對應的原碼/反碼)。

補碼的運算溢出怎麼辦

  • 例如 127 + 1 = 0111 1111 + 0000 0001 = 1000 0000-128,溢出)。
  • CPU 會設置 溢出標誌位(OF),由程序員處理。

總結

編碼 優點 缺點 適用場景
原碼 直觀 ±0 問題,運算複雜 早期計算機(已淘汰)
反碼 改進負數表示 ±0 仍存在,運算需調整 過渡方案(基本不用)
補碼 ±0 問題,運算簡單 負數計算稍複雜 現代計算機標準

補碼是計算機存儲和處理有符號整數的 最優方案,理解它對於學習 計算機組成原理、編程(如整數溢出)、逆向工程 都至關重要!

user avatar MMXXLL Avatar YueZone Avatar
Favorites 2 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.