(x&y)+((x^y)>>1)的原理分析

一、解释1

(x&y)+((x^y)>>1),把x和y里对应的每一位(指二进制位)都分成三类,每一类分别计算平均值,最后汇总。

1、是x,y对应位都是1,用x&y计算其平均值;

2、是x,y中对应位有且只有一位是1,用(x^y)相当于计算机这些位的和,>>1相当于除2;

3、是x,y中对应位均为0,无须计算。

二、解释2

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

当 x 为 729,y 为 271 时函数的返回值是多少?

思路最简单也最直接的就是将 x 和 y 都先转换为二进制,然后老老实实的做按位与,按位异或等运算,最后得出结果。

在分析该表达式的实现思路之前,首先说明该表达式的作用就是求两数的平均值。也就是说,像上面当 x 为 729,y 为 271 时函数的返回值是 500 。下面说明该表达式的思路。

我们先了解下面几种情况:

1. 当两个数所有为 1 和为 0 的位都相同时,这两个数的平均值就是 (x & y) 。比如当 x 和 y 都等于 1100 时,x & y 的值也是 1100 ,我们也可以说此时求 x 和 y 的平均数可以用 (x & y) 来求得。

2. 当两个数中的所有对应位有且只有一个为 1 时,那么这两个数的平均值由 (x^y)>>1 表达式求得。比如当 x 为 101100 (十进制 44),y 为 010010 (十进制 18) 时,x ^ y 的值为 111110 ,然后再将 111110 向右移动 1 位后得 11111 (十进制为 31),也就是 (44 + 18)/2 = 31 。

由上面的 情况1 和 情况2 我们知道,将它们两者结合起来便可求得随意两个整数的平均值。下面以 x 等于 12, y 等于 24 为例说明:

x 的二进制数位 1100 ,y 的二进制数为 11000 。我们先将 x 和 y 做相与运算:

01100
11000        &
--------------
01000

实际上,像上面的运算,我们也可以直接看成是 情况1 中的运算,即相当于执行:01000 & 01000 ,最后值仍然是 01000 。

好,经过上面的与运算后,看起来是将 01100 和 11000 分别去掉了 01000 这部分,所以剩下来的就是 00100 和 10000 。当我们执行 x^y 时:

01100
11000  ^
-----------
10100

由上可见,异或的运算正好也是去掉了 01000 ,然后将剩下来的 00100 和 10000 这两部分进行相加,所以求这两部分的平均数只要向右移动 1 位即可。

综上可得,我们求平均数的过程是先用与运算对数值做部分的提取,然后用异或并右移运算获得余下部分的平均值,因此这两部分的平均值相加后就得出了原来两数的平均值。实际上,这是一个加法分解然后综合的过程。如上面的 12 和 24,先做与运算,也就相当于从 12 和 24 里分别先减去 4,剩下 8 和 16,再将这两数相加得 24 (异或运算),然后再除以2(右移),结果为 12 。最后 12 + 4 等于 16 即得最后所要的结果。

尽管上面的过程看来上去实际用处不是很大,但如果是用在没有乘除法指令的简单单片机系统,移位和逻辑运算操作就显得很重要了。

转载自:

http://blog.csdn.net/sayaxiaopan/article/details/9301635

http://www.cnblogs.com/enthusiastic/archive/2012/10/01/2709802.html

使用(xy) + ((x^y)1) 求平均数相关推荐

  1. 平均数和均值一样吗_求平均数!

    一.问题: 输入4个整数,计算并输出平均数,保留小数点后1位. 二.分析: 这个问题,很简单,先获得输入的数字,再求和,然后除以4,最后输出结果即可. C语言如下: #include <stdi ...

  2. c语言用除法求平均数,论C语言两整数平均值的4种算法

    小学数学中我们就学过一种简单的求解两个整数平均数的算法(a+b)/2,当然它同样适用于我们的C语言#include #include int main() { int a = 10; int b =  ...

  3. python中平均数怎么取,python如何求平均数

    python求平均数的方法:首先新建python文件,并输入要计算的平均数:然后初始化sum总和的值:**后利用"总和/数量"的公式计算出平均数.97h少儿编程网-https:// ...

  4. 用数组实现求平均数小案例

    用数组实现求平均数的小案例:需求(在竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分(不考虑小数部分):选手的最后得分为:去掉一个最高分和一个最低分后 其余4个选手的平均值) packag ...

  5. java1.8 list stream求平均数

    1.8 stream求平均数 /* * 不允许list中存在为空的值,不然会异常 */ List list = Arrays.asList(0D, 1D, 1.2, 5.6); List intege ...

  6. 任意多个数字求平均数

    任意多个数字求平均数 我们在进行数据的平均计算时,通常采用先求和再除以数量进行平均的方法.但是这个方法有个隐患,就是如果进行平均的数字数量很多,求和时难免要溢出,导致错误结果. 为了解决这个问题,我们 ...

  7. JavaScript 求平均数的方法(实参个数不确定)

    求平均数的方法.要求: 传递的参数的个数不确定 去掉最高分和最低分 方法一 function average(){var max=Math.max(...arguments);var min=Math ...

  8. 学习笔记-DataFrame求平均数,求众数

    df = pd.DataFrame({'A': [1, 2, 1, 2, 1, 2, 3],'B':[1, np.NaN, 3, 2, 1, 3, 3]}) df >>> A B 0 ...

  9. C++——求平均数、求和函数

    accumulate定义在#include<numeric>中,作用有两个,一个是累加求和,另一个是自定义类型数据的处理 1.累加求和 int sum = accumulate(vec.b ...

最新文章

  1. 解决使用Dockerfile来build镜像时pip install遇到的BUG
  2. python编写赛车游戏单机版_使用Keras和DDPG玩赛车游戏(自动驾驶)
  3. mySQL:两表更新(用一个表更新另一个表)的SQL语句
  4. Shell 快速指南
  5. 数据结构之并查集:并查集解决案例, Python——21
  6. The type Resource is not accessible due to restriction on required library
  7. 总被业务当工具人,数据IT人怎么才能提高自己在公司的地位?
  8. 修改PHP上传文件的大小限制(post)
  9. 关于web前端性能优化总结
  10. arduino 下载 https://downloads.arduino.cc/packages/package_index.json error
  11. Linux下基于LDAP统一用户认证的研究
  12. POI(兴趣点)抓取工具
  13. 哔哩哔哩电脑网页版怎么下载视频
  14. CCNA:IOS设备管理配置
  15. sd卡烧写linux内核,linux下怎样烧写sd卡
  16. 算法实现- 数字转金额大写
  17. 笔记本开热点自动断开
  18. 计算机桌面有阴影,电脑桌面图标有蓝色阴影怎么去掉
  19. 美团外卖饿了么竞品分析:共生存?还是你死我亡?
  20. [答疑]举报卖家、举报买家还是举报

热门文章

  1. 设置子元素在主轴(横轴)方向上的对齐方式为容器的开头_今日推送 CSS Flexbox布局(上)...
  2. 混合云存储跨云灾备方案之跨云容灾
  3. SQL中游标的使用(转)
  4. matlab norm 范式
  5. DNS 映射解析应用(二)
  6. as3直接播放flv基本代码
  7. Windows 文件过滤驱动经验总结
  8. android 开发框架 怎么使用,Android快速开发框架dyh详解(二)---控件层的使用
  9. 24.两两交换链表中的结点
  10. Grid SearchCV(网格搜索)与RandomizedSearchCV (随机搜索) 贴近实践的