經典面試題:計算 (a + b) / 2 但**不能使用 `+`、`/` 運算子**。解法利用**位運算**:無進位加法 (XOR) + 進位 (AND<<1) 迭代,或直接右移一位 (算術右移)。
#include <stdio.h>
int average_shift(int a, int b) {
// (a + b) >> 1 等價於 (a + b) / 2 (向零取整)
// 注意:此處仍用了 +,若嚴格禁止 + 需用方法二
return (a + b) >> 1;
}
int main() {
int a = 6, b = 8;
printf("平均值 = %d\n", average_shift(a, b)); // 7
return 0;
}
int add_bitwise(int a, int b) {
while (b != 0) {
int sum = a ^ b; // 無進位加法
int carry = (a & b) << 1; // 進位
a = sum;
b = carry;
}
return a;
}
int average_bitwise(int a, int b) {
int sum = add_bitwise(a, b);
return sum >> 1; // 算術右移一位 = 除以 2
}
a b (a+b)/2 average_safe 備註 6 8 7 7 正常 -5 3 -1 -1 負數 (算術右移保留符號位) INT_MAX INT_MAX 溢出 UB INT_MAX **無溢出** INT_MIN INT_MIN 溢出 UB INT_MIN **無溢出** INT_MAX INT_MIN -1/2=0 0 正確 關鍵差異:算術右移 vs 邏輯右移
unsigned int average_unsigned(unsigned int a, unsigned int b) {
return (a & b) + ((a ^ b) >> 1); // 邏輯右移,標準保證
}
// 有號數轉換版
int average_safe_std(int a, int b) {
unsigned int ua = a, ub = b;
unsigned int avg = (ua & ub) + ((ua ^ ub) >> 1);
return (int)avg; // 依賴二進制補碼表示 (現代平台通用)
}
**工業級推薦**:`(a & b) + ((a ^ b) >> 1)` —— 無溢出、無除法、O(1)、標準合規 (配合無號轉換)。面試若問「不使用 + - * /」,則需實現 `add_bitwise` 迭代。理解**無進位加法 (XOR) + 進位 (AND<<1)** 是位運算加法的核心,可推廣至乘法、除法等更複雜運算。