(x&y) + ((x^y)>>1)即x和y的算数平均值

(x&y) + ((x^y)>>1)相当于(x+y)/2

(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,所以不用计算。 三部分汇总之后就是(x&y)+((x^y)>>1)

顺便解释一下前面说到可以避免溢出。

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

时间: 2024-08-11 05:35:15

(x&y) + ((x^y)>>1)即x和y的算数平均值的相关文章

将两个矩阵相乘,A为x行y列的矩阵,B为y行z列的矩阵,A*B

m1*m2=m其中是一个x行z列的一个矩阵,例如 代码如下: #include<stdio.h>void matrix_multiply(int *m1, int *m2, int *m, int x, int y, int z){ int row = 0;  //m矩阵的行 int col = 0;  //m的列 int k = 0; int *m1p = m1;     int *m2p = m2; for (row = 0; row < x; row++) {  for (col

hdu1695 GCD2 容斥原理 求x属于[1,b]与y属于[1,d],gcd(x,y)=k的对数。(5,7)与(7,5)看作同一对。

GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10992 Accepted Submission(s): 4157 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k

编写一个表示二维平面上的点的类MyPoint,满足以下条件: 1、定义private的成员变量x和y,表示点的x和y坐标,类型为double

编写一个表示二维平面上的点的类MyPoint,满足以下条件:1.定义private的成员变量x和y,表示点的x和y坐标,类型为double2.定义两个MyPoint的构造方法,一个构造方法不带参数,而且x和y的初始值为0,另一个构造方法有两个参数,参数名为x和y,类型为double,用这两个参数分别作为初始x和y坐标3.定义一个getD方法,有一个类型为MyPoint的对象参数,功能为返回当前对象和参数对象这两个坐标点的距离,返回值为double类型4.编写测试的main方法,调用getD计算两

matlab画二维直方图以及双y轴坐标如何修改另一边y轴的颜色

1.首先讲一下如何用hist画二维直方图 1 x=[-568179 -766698 -935586 -826865 -393971 -771826 -1529945 -1910695 -1694740 -926367 -306998 -844840 -1828334 -2062815 -2297296 -1498824 -411346 -827922 -1826636 -1844777 -1862918 -1881060 -746534 -100479 -845832 -1832756 -194

WPF DevExpress Chart控件多Y轴,指定数据参考的Y轴

当Chart中有两个及以上的Y轴时,我们就要指明图表中的柱子或折线对应的是哪个Y轴了,这时候需要指明柱子或者折线的dxc:XYDiagram2D.SeriesAxisY属性,来设置对应的Y轴(dxc:XYDiagram2D.SeriesAxisY="{Binding ElementName=y2}"),其中Binding的ElementName就是需要对应的Y轴的Name(即这里的y2),界面代码如下: <dxc:ChartControl DataSource="{Bi

Y combinator 的推导过程

最近在看<暗时间>,书中有Y组合子的推导过程,初看时很难理解,这里记录一下加深记忆,我们使用Scheme语言的语法. 我们知道Scheme中可以这样定义递归函数 (define (func n) (if (= n 0) 1 (* n (func (- n 1))))) 但是我们知道define这个函数只起到了一个语法糖的效果,再对应lambda表达式还未知的时候是不能使用这个函数. 接下来我们只通过使用lambda表达式来推导出递归函数. 我们先做一下尝试 (lambda (n) (if (=

y=x^2 vs y=x^(1/2)

[y=x^2 vs y=x^(1/2)] y=x^2,基础函数,废话不多说. y=x^(1/2),指数变成了上式的倒数.x^(1/2)即是,√x.但函数图像会是什么样呢?可以把y=x^(1/2),转变成y^2 = x.这样之后,发现与上式形式一样,只是把x轴.y轴颠倒了.所以将上图X.Y轴对调一下即可得y=x^(1/2)图像. 发现Y只有大于0的部分,因为根确定符号必须大于0.为了得到真正的旋转图像,将函数改一下即可.|y|=x^(1/2). 可以发现,此2等式关于y=x对称.

Y Combinator

由于匿名函数(通常成为lambda函数但是跟lambda calculus不同)在递归时无法获得函数名,从而导致一些问题,而Y Combinator能很好地解决这个问题.利用不动点的原理,可以利用一般的函数来辅助得到匿名函数的递归形式,从而间接调用无法表达的真正的匿名函数.下面以一个阶乘的递归来说明. #Python版本,后面会加上C++版本 #F(f) = f def F(f,n): return 1 if n==0 else n*f(n-1) #或者用lambda #F = lambda f

HDU 5297(Y sequence-Mobius函数容斥+迭代)

Y sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1192    Accepted Submission(s): 265 Problem Description Yellowstar likes integers so much that he listed all positive integers in asce