(a+b)/2 若 a,b 為大整數,a+b 可能溢位 (有號 UB,無號環繞)。
int avg_shift(int a, int b) {
return (a + b) >> 1; // 仍有溢位風險!
}
// 無號版安全:
unsigned int avg_unsigned(unsigned int a, unsigned int b) {
return (a >> 1) + (b >> 1) + (a & 1 & b & 1); // 處理最低位進位
}
int avg_safe(int a, int b) {
return a + (b - a) / 2; // 等價 (a+b)/2 但無溢位
// 或 (a & b) + ((a ^ b) >> 1) 位運算版
}
推導:a + (b-a)/2 = (2a + b - a)/2 = (a+b)/2。b-a 不會溢位 (同號差值絕對值較小)。
int avg_bitwise(int a, int b) {
return (a & b) + ((a ^ b) >> 1);
}
// 原理: a&b 保留同為1的位(進位), a^b 保留不同位(無進位和), 右移1位相加
double avg_double(double a, double b) {
return a + (b - a) * 0.5; // 同樣避免溢位 (雙精度範圍極大)
}
int main() {
int a = 2000000000, b = 2000000000;
printf("%d\n", avg_safe(a,b)); // 2000000000
printf("%d\n", avg_bitwise(a,b)); // 2000000000
return 0;
}