来自http://aggregate.org/MAGIC/#Average%20of%20Integers:
(low & high) + ((low ^ high) / 2)
是两个无符号整数的防溢出平均值。
现在,此技巧仅适用于无符号整数。但是因为
((a+x) + (b+x))/2 = (a+b)/2 +x,如果您具有与有符号整数相同的位大小的无符号整数,则可以按以下步骤进行伪造:
unsigned int u_low = low + MAX_INT + 1;unsigned int u_high = high + MAX_INT + 1;unsigned int u_avg = (u_low & u_high) + (u_low ^ u_high)/2;int avg = u_avg - MAX_INT - 1;
更新
:经进一步思考,即使您没有带符号的整数,这也将起作用。按位,有符号和无符号整数等效于加,减和布尔运算。因此,我们需要担心的是确保除法行为像无符号除法一样,我们可以通过使用shift并屏蔽掉最高位来做到这一点。
low += MAX+INT + 1;high += MAX_INT + 1;avg = (low & high) + (((low ^ high) >> 1) & MAX_INT);avg -= MAX_INT + 1;
(请注意,如果您使用的是Java,则可以使用无符号移位
... >>> 1而不是
(... >> 1) & MAX_INT。)
但是, 我偶然发现了一个更简单的选择,我还没有弄清楚它是如何工作的。无需通过MAX_INT调整数字或使用无符号变量或其他任何东西。很简单:
avg = (low & high) + ((low ^ high) >> 1);
与16位有符号整数所有组合进行试验
low,并
high在范围内-32768..32767,但尚未完全成熟(由我反正)。



