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

C 語言技巧:不使用條件語句求兩數最大值(位運算實現)

     編輯:關於C語言

無分支最大值算法

題目:求 max(a, b),**禁止使用** if、?:、switch、循環、比較運算符 (>, < 等)。

核心思路:符號位提取

對有符號整數 d = a - b:

  • d >= 0 (a ≥ b) → 最高位 (符號位) 為 0。
  • d < 0 (a < b) → 最高位為 1。

將符號位提取為 0/1 索引,查表選擇 a 或 b。

實現代碼

#include 

int max_no_branch(int a, int b) {
    int d = a - b;
    // 算術右移 31 位 (假設 32 位 int) 提取符號位
    // d >= 0 → 0x00000000 (0)
    // d < 0  → 0xFFFFFFFF (-1)
    // 轉無符號右移避免實現定義行為,再轉回 int
    int flag = (int)((unsigned int)d >> 31); // 0 或 -1
    
    // 利用 flag 全 0/全 1 特性進行位選擇
    // flag = 0  → 選 a (b & 0 = 0, a & ~0 = a)
    // flag = -1 → 選 b (b & -1 = b, a & 0 = 0)
    // 但更簡潔:用數組索引 (flag 轉為 0/1)
    int idx = (flag == 0) ? 0 : 1; // 這裡用了 ?: 違反題意,改用位運算轉換
    
    // 標準無分支轉換:flag 是 0 或 -1
    // (flag & 1) 即為 0 或 1
    int arr[2] = {a, b};
    return arr[flag & 1]; // flag=0 → 0; flag=-1 (0xFFFFFFFF) & 1 = 1
}

// 更優雅的純位運算版 (無數組)
int max_bitwise(int a, int b) {
    int d = a - b;
    int flag = (int)((unsigned int)d >> 31); // 0 或 -1
    // a ^ ((a ^ b) & flag)
    // flag=0: a ^ 0 = a
    // flag=-1: a ^ (a ^ b) = b
    return a ^ ((a ^ b) & flag);
}

int main() {
    int a, b;
    while (scanf("%d %d", &a, &b) == 2) {
        printf("max = %d\n", max_bitwise(a, b));
    }
    return 0;
}

關鍵技術點解析

  1. 無符號右移提取符號位:(unsigned)d >> 31 保證邏輯右移 (高位補 0),結果為 0 或 1。轉 int 得 0 或 -1 (0xFFFFFFFF)。
  2. 位選擇公式:a ^ ((a ^ b) & mask)。
    • mask = 0 → a ^ 0 = a。
    • mask = -1 (全 1) → a ^ (a ^ b) = b。
    這是無分支編程的核心模式,廣泛用於加密、圖形學、高性能庫。
  3. 溢出風險:a - b 可能溢出 (如 INT_MAX - (-1))。工程中若輸入範圍未知,需用無符號運算或更複雜的無溢出比較 (如 (a > b) - (a < b) 但用了比較)。

擴展:最小值

int min_bitwise(int a, int b) {
    int d = a - b;
    int flag = (int)((unsigned int)d >> 31);
    return b ^ ((a ^ b) & flag); // 只需交換 a/b 位置
}

性能對比

現代編譯器 (GCC/Clang -O2) 常自動將 max 優化為條件移動指令 (CMOV),無需手寫位運算。但理解原理對底層優化、逆向分析、編譯器開發大有裨益。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法指令數分支預測適用場景
a > b ? a : b少可能失敗通用,現代 CPU 分支預測極強
位運算無分支固定 5-6 條無分支SIMD、GPU、嚴格實時系統、避免旁路攻擊