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

C++ 位操作完全指南:定義、移位、常用技巧與循環移位實現

     編輯:C++ 入門

二進制字面量定義

C++ 無原生二進制字面量(C++14 起支持 0b 前綴),常用八進制(0 開頭)或十六進制(0x 開頭)表示位模式。例如:

  • int a = 0x80; 表示低 8 位為 1000 0000,高 24 位補 0,值為 128。
  • int a = -0x80; 為 -128(補碼表示)。
  • 字面量類型推導規則:優先匹配 int、unsigned int、long、unsigned long、long long、unsigned long long。可用 typeid(0xF0).name() 查看實際類型。

移位操作規則

操作行為備註
<< 左移低位補 0,高位丟棄等價於乘 2n(無溢出時)
>> 右移無符號數高位補 0;有符號數視編譯器定(GCC 為算術右移,補符號位)等價於除 2n(無符號/正數)

未定義行為(UB):移位量為負數,或移位量 ≥ 位寬(如 32 位 int 移位 ≥ 32)。嚴禁觸發。

十大經典位操作技巧

  1. 置位第 n 位:expr |= (1 << n);
  2. 清零第 n 位:expr &= ~(1 << n);
  3. 測試第 n 位:bool b = expr & (1 << n);
  4. 翻轉第 n 位:expr ^= (1 << n);
  5. 清除最低位的 1:expr &= (expr - 1);(可用於統計 1 的個數:循環清除直到為 0)
  6. 向右傳播最低位的 1:expr |= (expr - 1);(如 00101000 → 00101111)
  7. 判斷 2 的冪次:(expr & (expr - 1)) == 0(expr > 0)
  8. 清除右側連續 1:expr = ((expr | (expr - 1)) + 1) & expr;
  9. 判斷兩個 2 的冪次之差:((expr | (expr - 1)) + 1) & expr == 0(即二進制中所有 1 連續)
  10. 求下一個相同 1 個數的整數:
    int NextN(int N) {
        int x = N & (-N);      // 提取最低位 1
        int t = N + x;         // 進位
        return t | ((N ^ t) / x >> 2); // 調整低位
    }
    若不存在更大值則返回 -1。

循環移位實現(32 位整數為例)

int rotateLeft(int a, unsigned int n) {
    n %= 32;
    if (n == 0) return a;
    return (a << n) | ((a & 0xFFFFFFFFu) >> (32 - n));
}
int rotateRight(int a, unsigned int n) {
    n %= 32;
    if (n == 0) return a;
    return ((a & 0xFFFFFFFFu) >> n) | (a << (32 - n));
}

關鍵細節:

  • 右移前將 a 轉為無符號(& 0xFFFFFFFFu),避免負數算術右移填充符號位導致錯誤。
  • n %= 32 處理超寬移位;n == 0 早期返回,避免 32 - n == 32 導致 UB。

實戰示例

a = 0b01111011(123),循環左移 2 位:

b = a >> (8 - 2); // 取高 2 位 → 0b00000001
a = a << 2;       // 左移 → 0b11101100
a = a | b;        // 合併 → 0b11101101 (237)

結果與 rotateLeft(123, 2) 一致。

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