不使用 if、?、>、< 等比較/分支語句,僅用位運算實現 max(a, b)。
diff = a - b。a >= b,diff >= 0,符號位 (MSB) 為 0;若 a < b,diff < 0,符號位為 1(補碼表示)。sign = (diff & 0x80000000) >> 31(32 位 int)。結果為 0 或 1。int arr[2] = {a, b},返回 arr[sign]。int max(int a, int b) {
int arr[2] = {a, b};
// 取差值符號位:非負為 0,負為 1
int sign = ((a - b) & 0x80000000) >> 31;
return arr[sign];
}
| a | b | a-b | 符號位 | sign | arr[sign] | 結果 |
|---|---|---|---|---|---|---|
| 10 | 5 | 5 (正) | 0 | 0 | arr[0]=a | 10 ✓ |
| 5 | 10 | -5 (負) | 1 | 1 | arr[1]=b | 10 ✓ |
| -2 | -5 | 3 (正) | 0 | 0 | arr[0]=a | -2 ✓ |
a - b 可能溢出(如 INT_MAX - INT_MIN)。工程上應用無符號數轉換或編譯器內建函式(__builtin_clz 等)規避。a > b ? a : b 會自動生成條件移動指令 (CMOV),無需手寫位運算技巧。min、abs、sign 等無分支運算。利用補碼符號位特性,配合陣列索引選擇,巧妙繞過比較分支。此類位運算技巧屬於「黑客技藝」,理解其原理有助於閱讀底層庫代碼,但生產環境優先可讀性與編譯器優化。