首先,我们必须理解的是“任意一个二进制数都可以表示为各个位和其权值乘积的和的形式”。如果对二进制数不懂的话,可以参照下面十进制数:
十进制数31 = 3*10^1 + 1*10^0
对于这里的3,它的权值为10^1,而1的权值为10^0
二进制数0110(即十进制数6) = 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0
同理,最左边的0它的权值为2^3,从左往右第一个1的权值为2^2,第二个1的权值为2^1,最右边0的权值为2^0
由此,我们也可以总结出对于任意一个二进制数,它的第n位的权值为2^(n-1)。
当知道权值的概念后,读者只需要看懂下面两段话,相信你一定会理解通过位运算求平均值的原理 。
如果两个二进制对第n位相加时,如果该位两个都为1(可以通过异或的办法判断),则相加后为2 * 2^(n-1)(其中2^(n-1)为第n位的权值,不考虑进位的话,第n位此时的值应为2,故得到该表达式) ;如果 一个为1,一个为0(可以通过按位与的办法判断),则相加后为1 * 2^(n-1)。
假设两个二进制数分别为:0100, 0101。则相加可以表示为:
0100 + 0101 = (2 * (0100 & 0101)) + (0100 ^ 0101)
而二进制乘以2相当与将二进制数左移一位,除以2相当于将二进制数右移一位,以上是求出了两个二进制数的和,而要求出平均值,在上面的基础上除以2。即
(1010 + 0101) / 2 = (0100 & 0101) +((0100 ^ 0101)>> 2)
需要注意的是计算机真正采用这种方法计算两个二进制数的平均值时,并不是先求和再求平均值,而是直接通过位运算计算得出,因此并不存在溢出的情况。
如果读者对此还有什么疑问,或者本文哪里有不对的地方,欢迎评论留言。