用位操作求两个数的平均值

    用位操作实现求两个数a和b的平均值,只需将两个数的相同位提取出来,再将不同的位加在一起除2(即右移一位),用表达式说明即为:((a & b) + (a ^ b) >> 1),用这样的方式计算两个数的平均值可以防止数据溢出。但是请记住用这个表达式算出的结果永远是不超过真实平均值的最大整数,即若真实结果是-5.5,则此表达式给出的结果是-6,若真实平均值是-5,则表达式的结果是-5。

    现在解释一下这个表达式的原理,求两个数的平均值我们把这两个操作数分成二进制位相同的部分和二进制位不同的部分,例如a=5(0101),b=6(0110),他们相同的部分为a0=0100,b0=0100,他们不同的部分为a1=0001,b1=0010,则:

    (a + b) / 2 = (5 + 6) / 2

                  <=> ((0100 + 0001) + (0100 + 0010)) >> 1                                                  (1)

                  <=> ((0100 + 0100) + (0001 + 0010)) >> 1                                                  (2)

                  <=> (0100 + 0100) >> 1 + (0001 + 0010) >> 1                                             (3)

                  <=> 1000 >> 1 + 0011 >> 1                                                                      (4)

                  <=> 0100 + 0011 >> 1                                                                              (5)

                  <=> 0101

                    = 5

    由以上(5)式即知(a + b) / 2 就是 ((a & b) + (a ^ b) >> 1),但是如果结果是负的浮点数,则这两个数表达式的结果并不一样,(a + b) / 2 的结果是对浮点结果取整,取整的方式是直接去掉小数,而((a & b) + (a ^ b) >> 1) 的结果是不超过结果的最大整数。

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int a;
 6     int b;
 7 
 8     scanf ("%d%d", &a, &b);
 9     while ((0 != a) || (0 != b))
10     { 
11         printf ("\n用 (a + b) / 2 计算的 %d 和 %d 的平均值为:\n", a, b);
12         printf ("%d\n", (a + b) / 2);
13 
14         printf ("\n用 ((a & b) + ((a ^ b) >> 1)) 计算的 %d 和 %d 的平均值为:\n", a, b);
15         printf ("%d\n\n", ((a & b) + ((a ^ b) >> 1)));
16 
17         scanf ("%d%d", &a, &b);
18     }
19 
20     return(0);
21 }

posted on 2013-04-02 14:35  ldjhust 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/ldjhust/archive/2013/04/02/2995475.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值