在 C 語言中,原碼、反碼、補碼的運算規則與其編碼特性密切相關,核心差異體現在符號位是否參與運算、進位如何處理以及減法是否能轉化為加法等方面。以下是三者的運算規則及特點分析(以 8 位整數為例,符號位為最高位):
一、原碼的運算規則
原碼是 “符號位 + 數值絕對值” 的直接表示,其運算規則需單獨處理符號位,且加法和減法需分開邏輯,靈活性差。
1. 加法運算
- 若兩數符號相同(同正或同負):
符號位不變(仍為 0 或 1),數值位直接相加;若數值位相加后有進位,結果可能溢出(超出表示范圍)。
示例:+3(00000011) + +5(00000101)
符號位均為 0,數值位相加:0000101 + 000011 = 0001000,結果為00001000(+8,正確)。
- 若兩數符號不同(一正一負):
需先比較兩數數值位的絕對值大小,用 “大絕對值 - 小絕對值”,結果的符號取 “絕對值大的數” 的符號。
示例:+5(00000101) + (-3)(10000011)
絕對值 5 > 3,符號取正(0),數值位相減:0000101 - 0000011 = 0000010,結果為00000010(+2,正確)。
2. 減法運算
原碼減法需轉化為 “被減數 + 減數的相反數”,再按加法規則處理(符號相反時的加法邏輯)。
示例:+5(00000101) - (+3)(00000011)
等價于 +5 + (-3),按符號不同的加法規則計算,結果為 + 2(正確)。
原碼運算的缺陷
- 符號位需單獨判斷,運算邏輯復雜(需比較絕對值、區分加減);
- 存在兩個 0(+0 和 - 0),可能導致運算結果歧義;
- 實際中幾乎不用于計算機運算(僅用于直觀表示)。
二、反碼的運算規則
反碼是原碼到補碼的過渡編碼,其運算規則允許符號位參與運算,但需處理 “循環進位”(最高位進位需回加到最低位),可實現減法轉加法,但仍有缺陷。
1. 加法運算
- 符號位與數值位一起參與加法(按二進制加法規則,逢 2 進 1);
- 若最高位(符號位)產生進位,需將該進位 “循環” 加到結果的最低位(稱為 “循環進位”);
- 運算結果仍為反碼,需轉換為原碼才能得到實際值。
示例 1:+3(反碼00000011) + +5(反碼00000101)
直接相加:00000011 + 00000101 = 00001000(無進位),結果反碼為 00001000,對應原碼 + 8(正確)。
示例 2:+5(反碼00000101) + (-3)(反碼11111100)
相加:00000101 + 11111100 = 100000001(最高位產生進位 1);
循環進位:將進位 1 加到最低位,00000001 + 1 = 00000010;
結果反碼為 00000010,對應原碼 + 2(正確)。
示例 3:+1(反碼00000001) + (-1)(反碼11111110)
相加:00000001 + 11111110 = 11111111(無進位);
結果反碼為 11111111,對應原碼 - 0(存在雙 0 問題,不完美)。
2. 減法運算
反碼減法可直接轉化為 “被減數 + 減數的反碼”(因負數的反碼是其相反數的反碼),再按加法規則處理(含循環進位)。
示例:+5 - (+3) 等價于 +5 + (-3),同上述示例 2,結果正確。
反碼運算的缺陷
- 需處理循環進位,硬件實現稍復雜;
- 仍存在 - 0(11111111),導致 0 的表示不唯一;
- 未徹底解決運算問題,僅作為補碼的過渡。
三、補碼的運算規則
補碼是計算機中實際使用的編碼,其運算規則最簡單:符號位直接參與運算,進位直接丟棄,減法可完美轉化為加法,且結果唯一正確。
1. 加法運算
- 符號位與數值位一起參與加法(按二進制加法規則,逢 2 進 1);
- 若最高位(符號位)產生進位,直接丟棄該進位(因超出位數的部分不影響結果);
- 運算結果仍為補碼,無需額外處理即可表示正確值。
示例 1:+3(補碼00000011) + +5(補碼00000101)
相加:00000011 + 00000101 = 00001000(無進位),結果補碼為 00001000,對應 + 8(正確)。
示例 2:+5(補碼00000101) + (-3)(補碼11111101)
相加:00000101 + 11111101 = 100000010(最高位產生進位 1);
丟棄進位:結果為 00000010,對應 + 2(正確)。
示例 3:+1(補碼00000001) + (-1)(補碼11111111)
相加:00000001 + 11111111 = 100000000(進位 1);
丟棄進位:結果為 00000000(唯一的 0,正確)。
2. 減法運算
補碼減法可直接轉化為 “被減數 + 減數的補碼”(因減去一個數 = 加上它的相反數,而負數的補碼是其相反數的補碼),再按加法規則處理(進位丟棄)。
公式:a - b = a + (-b)的補碼
示例:+5 - (+3) = +5 + (-3)的補碼
-3 的補碼為 11111101,相加結果同示例 2,得 + 2(正確)。
補碼運算的優勢
- 符號位自然參與運算,無需單獨判斷;
- 減法完全轉化為加法,簡化硬件設計(只需加法器);
- 只有一個 0(00000000),結果無歧義;
- 進位直接丟棄,邏輯簡單,是計算機中整數運算的唯一實現方式。
四、無符號數的運算規則
無符號數(unsigned)沒有符號位,其原碼、反碼、補碼完全相同(即二進制數值本身),運算規則為:
- 加法:按二進制加法,進位直接丟棄(超出位數的部分無效);
- 減法:按二進制減法,若被減數小于減數,結果為 “模” 減去(減數 - 被減數)(等價于補碼運算,因無符號數的補碼即自身)。
示例(8 位無符號數):5 - 10
等價于 5 + (256 - 10) = 5 + 246 = 251(因 8 位無符號數的模為 256),結果為 251(正確,無符號數減法的 “借位” 通過模運算處理)。
總結
編碼 | 加法規則 | 減法規則 | 核心特點 |
原碼 | 符號位單獨處理,異號需比較絕對值 | 轉化為 “被減數 + 相反數”,同加法 | 邏輯復雜,有雙 0,幾乎不用 |
反碼 | 符號位參與運算,進位循環到最低位 | 轉化為 “被減數 + 減數的反碼” | 需循環進位,仍有 - 0,過渡編碼 |
補碼 | 符號位參與運算,進位直接丟棄 | 轉化為 “被減數 + 減數的補碼” | 邏輯簡單,無歧義,計算機實際使用 |
補碼的運算規則是 C 語言中整數存儲和運算的基礎,理解其規則可解釋負數運算、溢出(如int a = 127 + 1結果為 - 128)等現象。