Analysis of (x&y)+((x^y)>>1)

Topic source: "Programmer Interview Collection (Fifth Edition)"

refer to:

https://zhidao.baidu.com/question/311282248.html Baidu knows an answer, very detailed

(x&y)+((x^y)>>1) This blog explains another approach



Original title:

int f (int x, int y)
{
    return (x&y)+((x^y)>>1);
}
f(729,271)=   



(x&y)+((x^y)>>1)  The book analyzes that the function of this function is to take the average of two numbers.

I don't quite understand, I checked the information and sorted it out, just for the record.


One explanation is:


Divide each bit (referring to binary bits) corresponding to x and y into three categories, calculate the average value for each category, and finally summarize.

in,

One is that the corresponding bits of x and y are all 1, and the average value is calculated by x & y;

One is that the corresponding bits in x and y have and only one bit is 1, and the average value is calculated by (x^y)>>1;

Another is that the corresponding bits in x and y are all 0, and no calculation is required.


Explain in detail how it is calculated:

1. The corresponding bits of x and y are both 1. After adding them and dividing by 2, the original number is still the same. For example, if two 00001111 are added and divided by 2, they still get 00001111. This is the first part.


2. In the second part, there is one and only one corresponding bit is 1, which is extracted by the "exclusive OR" operation, and then >>1 ( shift one bit to the right, which is equivalent to dividing by 2 ), that is, the average to the second part value.


3. In the third part, the corresponding bits are all zero, because it is still 0 after adding and dividing by two, so there is no need to calculate.

After the three parts are summarized, it is (x&y)+((x^y)>>1)


By the way, to explain earlier that overflow can be avoided.

假设x,y均为unsigned char型数据(0~255,占用一字节),显然,x,y的平均数也在0~255之间,但如果直接x+y可能会使结果大于255,这就产生溢出,虽然最终结果在255之内,但过程中需要额外处理溢出的那一位,在汇编中就需要考虑这种高位溢出的情况,如果(x&y)+((x^y)>>1)计算则不会。



另外一种解释是:


将a和b拆成两部分的平均值相加:
a、b对应位相同部分,a、b对应位不同部分。
a&b计算的是两个数用二进制表示时对应位相同的部分的平均,由于是取平均,所以若对应位相同则取其中一个数即可,所以用与操作;
a^b>>1计算的是对应位不同的部分的平均,也就是一个是0一个是1,那么平均就是(0+1)/2,就是异或并移位

(右移一位,相当于除以2的结果。 


举一个十进制的例子: 
计算14和6的平均值,拆分数字:14=6+8,6=6+0.相同部分两个6,取一个,不同部分8和0,取(8+0)/2=4。那么结果就是6+4=10就是所要求的答案。


个人觉得第二种比较方便理解。

一种解释是:


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324777384&siteId=291194637