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

C語言整數表示與位運算全攻略:原碼反碼補碼到實戰技巧

     編輯:關於C語言

機器數與真值

  • 機器數:計算機內部二進制表示,最高位為符號位(0 正、1 負)
  • 真值:機器數對應的實際數學值
  • 8 位機器數範圍:`[10000000, 01111111]` → 真值 `[-127, +127]`(原碼)

三大編碼體系

編碼正數負數0 的表示範圍(8位)
原碼符號位+絕對值符號位+絕對值+0 `00000000`、-0 `10000000`[-127, +127]
反碼同原碼符號位不變,其餘位取反+0 `00000000`、-0 `11111111`[-127, +127]
補碼同原碼反碼+1唯一 `00000000`[-128, +127]

為什麼計算機統一採用補碼?

  1. 統一加法器:減法轉為加法(`A - B = A + (-B)`),符號位參與運算,硬件簡單
  2. 零表示唯一:避免 `+0/-0` 判邏輯
  3. 擴展範圍:多表示一個最小值 `-128`(`10000000`)
  4. 溢出自然截斷:模 `2^n` 運算,高位丟棄即為正確結果

驗證:`1 + (-1)` 在補碼中 → `00000001 + 11111111 = 100000000` → 截斷高位 → `00000000` = 0 ✓

位運算完整速查表

運算符名稱規則範例(9=1001, 5=0101)核心規律
`&`按位與同為1得19&5=1 (0001)&1 保留、&0 清零
`|`按位或有1得19|5=13 (1101)|1 置位、|0 保留
`^`按位異或不同得19^5=12 (1100)同值得0、異值得1、x^x=0、x^0=x
`~`按位取反0↔1(含符號位)~9 = -10負數補碼存儲,~x = -x-1
`<<`左移高位丟棄,低位補05<<1 = 10x<
`>>`右移低位丟棄,符號位複製-10>>1 = -5算術右移保持符號,x>>n ≡ x/2ⁿ

位運算實戰技巧庫

1. 奇偶判斷(極速)

if (n & 1) puts("奇數"); else puts("偶數");  // 比 n%2 快,無分支預測失敗

2. 無臨時變量交換

a ^= b; b ^= a; a ^= b;  // 任意類型,無溢出風險

3. 2 的冪次判斷/對齊

// 判斷是否為 2 的冪次
bool is_pow2(unsigned n) { return n && !(n & (n-1)); }

// 向上對齊到 2 的冪次(如內存對齊)
size_t align_up(size_t n, size_t alignment) {
    return (n + alignment - 1) & ~(alignment - 1);
}

4. 快速乘除優化

  • `x * 8` → `x << 3`
  • `x / 8` → `x >> 3`(正數/無符號)
  • 編譯器 `-O2` 會自動優化,手寫僅用於嵌入式無優化編譯器或特定算法(如堆索引計算 `i>>1`)

5. 位掩碼提取/設置/清除/翻轉

#define BIT(n) (1U << (n))
#define GET(x, n) ((x) & BIT(n))
#define SET(x, n) ((x) |= BIT(n))
#define CLR(x, n) ((x) &= ~BIT(n))
#define FLIP(x, n) ((x) ^= BIT(n))

補碼視角的模運算統一理論

有限位寬 `w` 下,補碼運算等價於 **模 `2^w` 同餘運算**:

  • 無符號數:`[0, 2^w-1]` 完整剩餘系
  • 有符號數:`[-2^{w-1}, 2^{w-1}-1]` 對稱剩餘系
  • 轉換:`(signed)x = (x < 2^{w-1}) ? x : x - 2^w`

這解釋了為什麼 `unsigned` 與 `signed` 混合運算按無符號規則進行(C 標準規定),且補碼加減乘指令完全通用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved