【程序员面试宝典】(x&y)+((x^y)>>1)

原文地址:点击打开链接

原文参考地址:点击打开链接

下面代码:

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

f(729,271)=    

解法:
x&y是取相同的位与,这个结果是x和y相同位的一半,x^y是取不同的位,右移相当于除以2,所以这个函数的功能是取两个数的平均值。

具体思路参考:http://zhidao.baidu.com/question/311282248.html
(x&y)+((x^y)>>1),把x和y里对应的每一位(指二进制位)都分成三类,每一类分别计算平均值,最后汇总。其中,一类是x,y对应位都是1,用x&y计算其平均值;一类是x,y中对应位有且只有一位是1,用(x^y)>>1计算其平均值;还有一类是x,y中对应位为0,无需计算。

具体的计算过程为:
第一部分,x,y对应位均为1,相加后再除以2还是原来的数,如两个00001111相加后除以2仍得00001111;
第二部分,对应位有且只有一位为1,用“异或”运算提取出来,然后>>1(右移一位,相当于除以2),即得到第二部分的平均值;
第三部分,对应位均为0,相加后除以2还是0,所以不用计算。

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值