现在的位置: 首页 > 综合 > 正文

求平均值您都不会!信不信?有种你试试!

2019年05月11日 ⁄ 综合 ⁄ 共 3904字 ⁄ 字号 评论关闭
文章目录

二个整型数求其平均值,这个问题有人说,小学生都会. c=(a+b)/2

是的.这是一个很简单的问题.程序员一定也会.可是我们在会的时候,却忘记了会溢出,因为二个整型数相加之后可能会大于int.Max

如果是这样的话,那我们按上面的公式求出来的值还会正确吗.但是我们知道它们的平均值是肯定不会溢出

 

来看一下下面的代码.轻松解决了这个问题.

int average(int x, int y)  //返回X,Y 的平均值
{   
    return (x&y)+((x^y)>>1);
}

不信你可以试一下.看看正确吗

----------------------------

评论

#xfli 发表于2008-08-06 12:35:10  IP: 219.142.29.*
更轻松的方法是:
return (x/2 + y/2);

return ( (x>>1) + (y>>1) );
这样也不会溢出,而且可读性高。
#eagleyan 发表于2008-08-06 13:28:15  IP: 202.108.130.*
xfli 的方法在两个奇数的情况下对么?
#hjh5303 发表于2008-08-06 14:35:13  IP: 218.247.176.*
xfli 的方法在两个奇数明显不对,呵呵
#gonetime 发表于2008-08-06 16:38:16  IP: 202.114.0.*
受教了、、
#huanxu20011572 发表于2008-08-06 17:07:02  IP: 202.111.188.*
发现自己,技术太粗糙了
#111 发表于2008-08-07 09:21:22  IP: 124.156.97.*
xfli 的方法明显不对。。
由于X,Y取的是整型,如果取奇数,X/2 数据就会丢失,如:当X=3,Y=3,X/2=1而不会等于1.5,Y/2=1也不会等于1.5,这样平均值就等于2了。
为了避免数据丢失,我门应该把X,Y的数据类型变成 double类型。
#sherry_zhu 发表于2008-08-07 10:01:27  IP: 218.241.224.*
貌似楼主的方法只适应于大于0的整数
#chinaduan 发表于2008-08-07 14:28:19  IP: 202.127.112.*
(A+B)/X=A/X+B/X+(A/X+B/X)/X
#innexy_sun 发表于2008-08-07 15:13:16  IP: 218.24.167.*
不知道(x+y)>>1行不行?
问下你这种求平均值的方法数学依据是什么?
#innexy_sun 发表于2008-08-07 15:13:27  IP: 218.24.167.*
不知道(x+y)>>1行不行?
问下你这种求平均值的方法数学依据是什么?
#innexy_sun 发表于2008-08-07 15:13:29  IP: 218.24.167.*
不知道(x+y)>>1行不行?
问下你这种求平均值的方法数学依据是什么?
#innexy_sun 发表于2008-08-07 15:13:53  IP: 218.24.167.*
不好意思 发多了。。。。
#innexy_sun 发表于2008-08-07 15:22:11  IP: 218.24.167.*
我想把我的删掉。。。
但是怎么删?
#guolude 发表于2008-08-08 00:19:29  IP: 218.204.135.*
楼上(x+y)>>1也会溢出,和楼主指出的问题是一回事...
#neuwxw12345 发表于2008-08-08 09:56:07  IP: 202.118.2.*
int average(int x, int y) //返回X,Y 的平均值
{
return (x/2+y/2+(x%2+y%2)/2);
}

#jack_yyp 发表于2008-08-08 10:14:33  IP: 61.140.111.*
高明!
求平均数,相同的位,相加再求平均,就相当于该位;不相同的位,相加求平均,就相当于异或后左移一位!
高,实在是高!
#neuwxw12345 发表于2008-08-08 10:24:45  IP: 202.118.2.*
好似是异或后右移一位吧 呵呵
不过楼上解释的够清晰
我开始还没有看明白呢
#println4 发表于2008-08-08 10:31:27  IP: 61.153.145.*
受教了
#println4 发表于2008-08-08 10:31:49  IP: 61.153.145.*
受教了
#wooden954 发表于2008-08-08 14:17:10  IP: 121.18.79.*
Super聪明!
#wooden954 发表于2008-08-08 15:07:15  IP: 121.18.79.*
对楼主代码测试,测试结果如下:
a= 123,b= 234,c= 178
a=-123,b= 234,c=-2147483593
a= 123,b=-234,c= 2147483592
a=-123,b=-234,c=-179
测试结论:
当a,b符号不一致时,其结果不正确
测试人:wooden
测试日期:2008.08.08 14:36
修改方案
int average(int x, int y){ //返回X,Y 的平均值
return (x^y<0)?((x+y)/2):((x&y)+((x^y)>>1));
}
对新方案测试
a= 123,b= 234,c= 178
a=-123,b= 234,c= 55
a= 123,b=-234,c=+55
a=-123,b=-234,c=-179
测试结论:
当a,b符号不一致时,其结果正确
#Thinkingback 发表于2008-08-08 17:01:12  IP: 222.85.84.*
这个式子

a + ( b - a ) / 2

#tonghuasanren 发表于2008-08-08 17:07:34  IP: 221.11.22.*
楼上的考虑是很周全,很精明!
虽然和主题有一点点矛盾
return (x^y<0)?((x+y)/2):((x&y)+((x^y)>>1));
这里(x+y)/2 就是楼主所说的溢出,但是这里很聪明
是当其符号不一致时采用的相加模式,因而不会溢出
只是忽略了一点奇数问题 能给个更完善的解决方法么?
呵呵
#iwillalwaysloveyou 发表于2008-08-08 22:02:34  IP: 123.116.146.*
楼主的程序没问题,我试过了
#garfileo 发表于2008-08-18 19:24:27  IP: 222.134.129.*
用来展示一下奇技淫巧,的确不错。但现实中要是这样子写代码,累也累死了。因为不只有整数加法会溢出,整数的乘法也有可能溢出,此外还有浮点数的运算也会存在溢出现象。还有,这样的代码可读性也是个问题。
#suxiaojack 发表于2008-08-19 11:04:34  IP: 119.163.114.*
既然要求准确就用专业数学库最好。普通的情况无需这样写。
#听云 发表于2008-08-19 12:07:37  IP: 61.148.97.*
最主要的是这种求平均值的方法只能用于2个数,不能用于多个数.....
#freeliving 发表于2008-08-19 15:51:35  IP: 222.130.240.*
if(x > y)
temp = y + (x-y)/2;
else
temp = x + (y-x)/2;
这样可读性比较强点吧
#bacoo_zh@163.com 发表于2008-08-20 10:18:10  IP: 116.3.6.*
return
(x>>1)+(y>>1)+(x&1&y)+(((x&1)^(y&1))&(((x>>31&1)&(~x&1))^((y>>31&1)&(~y&1))));
#bacoo_zh@163.com 发表于2008-08-20 10:25:19  IP: 116.3.6.*
return (float)x/2+(float)y/2;
#ykwmz 发表于2008-08-20 23:24:22  IP: 60.186.23.*
C = a/2.0 + b/2.0
#elangno1 发表于2008-08-22 10:20:07  IP: 218.19.157.*
C = a/2.0 + b/2.0
严重支持
#bambooman 发表于2008-08-22 17:53:41  IP: 219.239.52.*
在嵌入式开发中还是用得着的, 如果是应用开发,只能算是中hack用法了,一开始设计就要避免 x+y>int.MAX了。
#zolo 发表于2008-08-25 11:33:00  IP: 220.249.74.*
我用devc++测试
#include <iostream>
using namespace std;

int average(int x, int y) //·µ»ØX,Y µÄƽ¾ùÖµ
{
return (x&y)+((x^y)>>1);
}

int main()
{
cout<<average(123,-234);
getchar();
return 0;
}

结果是 -56

不知道wooden是用什么怎么测试的。。

#yueshangchuanqi 发表于2008-08-25 16:44:41  IP: 121.35.224.*
刚入门的我感觉return (x/2 + y/2);
更容易理解,那个">>",我还没学到,看不懂呢。
#CrazyAzreal 发表于2008-08-26 09:42:45  IP: 121.15.134.*
我觉得小题大作了,应该是根据应用来决定使用方法。
#gary1969 发表于2008-11-05 16:26:54  IP: 125.119.235.*
return ((long)x + (long)y)/2;

抱歉!评论已关闭.