首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

原碼、反碼、補碼完整圖解:從定義到數學證明

     編輯:關於C語言

原碼、反碼、補碼完整圖解:從定義到數學證明

計算機內部以二進制補碼表示有符號整數,這背後蘊含著巧妙的數學原理。本文從機器數/真值概念入手,詳細推導原碼、反碼、補碼定義與轉換規則,並用同餘理論證明「為何補碼能將減法轉為加法」,最後解釋 int32 範圍 [-2³¹, 2³¹-1] 的由來。

一、機器數與真值

  • 機器數:帶符號位的二進制編碼,最高位 0 表正、1 表負。
    例:+3 → 00000011,-3 → 10000011(8 位)。
  • 真值:機器數對應的實際數值。
    例:10000011 真值 = -3,而非無符號值 131。

二、三種編碼定義與計算(以 8 位為例)

轉換規則:

  • 正數:三碼相同。
  • 負數原碼:符號位 1,其餘為絕對值二進制。
  • 負數反碼:符號位不變,其餘位取反。
  • 負數補碼:反碼 + 1(或原碼取反 + 1)。

三、為何需要反碼與補碼?

1. 原碼缺陷:符號位參與運算導致減法錯誤

1 - 1 = 1 + (-1)
原碼:[00000001] + [10000001] = [10000010] = -2  ❌

硬體電路若辨別符號位再決定加減,設計極其複雜。

2. 反碼修正減法,但引入「±0」問題

反碼:[00000001] + [11111110] = [11111111] = -0  ❌

真值正確,但存在 [00000000]=+0 和 [10000000]=-0 兩個編碼,浪費一個編碼且邏輯不清。

3. 補碼完美解決:唯一 0 編碼 + 多表示一個最小值

補碼:[00000001] + [11111111] = [00000000] = 0  ✅
  • 00000000 唯一表示 0。
  • 10000000 表示 -128(原碼/反碼無法表示)。
  • 8 位補碼範圍:[-128, +127],比原/反碼 [-127, +127] 多一個值。

四、數學本質:同餘理論與鐘面模型

1. 同餘定義

a ≡ b (mod m) 意為 a mod m = b mod m。負數取模規則:x mod y = x - y × floor(x/y)。
例:-1 mod 128 = 127,-2 mod 12 = 10。

2. 鐘面類比

12 小時鐘面:
往回撥 2 小時 ≡ 往前撥 10 小時(因 -2 ≡ 10 (mod 12))。
同理,二進制 n 位系統模數 M = 2ⁿ(補碼)或 2ⁿ-1(反碼)。

3. 反碼證明(模 127)

-1 的反碼 11111110 → 去符號位 = 126
-1 ≡ 126 (mod 127)
2 - 1 ≡ 2 + 126 (mod 127) → 結果模 127 同餘 = 1 ✅

4. 補碼證明(模 128)

-1 的補碼 11111111 → 去符號位 = 127
-1 ≡ 127 (mod 128)
2 - 1 ≡ 2 + 127 (mod 128) → 結果模 128 同餘 = 1 ✅

補碼將模數從 127 擴展到 128,故能多表示 -128(對應 10000000)。

五、工程應用:32 位有符號整數範圍

  • 最高位為符號位,剩餘 31 位表示數值。
  • 補碼編碼下,範圍 [-2³¹, 2³¹-1] = [-2147483648, 2147483647]。
  • 最小值 -2147483648 對應補碼 0x80000000,無原碼/反碼表示。

六、總結

  1. 原碼直觀但不適合硬體運算。
  2. 反碼修正減法,但有 ±0 問題。
  3. 補碼基於模運算同餘原理,完美解決 ±0 並多表示一個最小值,成為通用標準。
  4. 理解同餘與模運算,是掌握計算機算術本質的鑰匙。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
數值原碼反碼補碼
+10000 00010000 00010000 0001
-11000 00011111 11101111 1111