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

C/C++ 位運算完全指南:技巧、公式與實戰應用總匯

     編輯:關於C

位運算口訣速記

清零取反要用與,某位置一可用或
若要取反和交換,輕輕鬆鬆用異或

移位運算核心規則

運算子行為備註
<< 左移右補 0,左邊位元捨棄等價乘 2n(無溢出前提)
>> 右移右邊位元捨棄,左邊:正數補 0,負數視實作定義(算術/邏輯位移)等價除 2n(無溢出前提)
>>> 無符號右移左邊一律補 0Java/C# 專有,C/C++ 無此運算子

三大基本位運算應用模式

& (按位與) —— 掩碼 mask 中目標位為 0,其餘為 1

  • 清零特定位:x &= ~(1 << k)
  • 取指定位值:(x >> k) & 1

| (按位或) —— 掩碼 mask 中目標位為 1,其餘為 0

  • 置位特定位:x |= (1 << k)

^ (按位異或) —— 掩碼 mask 中目標位為 1,其餘為 0

  • 翻轉特定位:x ^= (1 << k)
  • 無暫存變數交換:a ^= b; b ^= a; a ^= b;

補碼運算核心恆等式

-x = ~x + 1 = ~(x - 1)
~x = -x - 1
x + y = (x | y) + (x & y)
x - y = (x | ~y) - (~x & y)
x ^ y = (x | y) - (x & y)

經典實戰技巧速查表

功能位運算寫法備註
判斷奇偶(x & 1) == 1 奇 / == 0 偶
取第 k 位(x >> k) & 1k 從 0 起算
清第 k 位x &= ~(1 << k)
置第 k 位x |= (1 << k)
循環左移 kx = (x << k) | (x >> (n-k))n 為位寬
無溢出平均值(x & y) + ((x ^ y) >> 1)避免 (x+y) 溢出
判斷 2 的冪(x & (x-1)) == 0 && x != 0
絕對值 (無分支)y = x >> 31; return (x ^ y) - y;32 位 int
模 2nx & (2n - 1)等價 x % (1<<n)
乘 2nx << n
除 2nx >> n負數行為視實作定義

進階位元技巧

// 取末 k 位:           x & ((1 << k) - 1)
// 末 k 位置 1:          x | ((1 << k) - 1)
// 末 k 位翻轉:          x ^ ((1 << k) - 1)
// 右側連續 1 變 0:     x & (x + 1)
// 右側首個 0 變 1:     x | (x + 1)
// 右側連續 0 變 1:     x | (x - 1)
// 取右側連續 1:        (x ^ (x + 1)) >> 1
// 去掉右起首 1 左側:   x & (x ^ (x - 1))

實戰範例:計算區間 [y, x] 間 1 的個數

int countOnesInRange(int x, int y, unsigned short k) {
    int cnt = 0;
    for (int i = y; i <= x; i++)
        cnt += (k >> (i - 1)) & 1;
    return cnt;
}

避坑指南

  • 右移負數行為為實作定義(Implementation-defined),跨平台需謹慎
  • 移位量 ≥ 位寬屬未定義行為
  • 有號整數溢出屬未定義行為,無號整數則模 2n 環繞
  • 優先使用無號類型進行位運算,避免符號位干擾
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved