关于两个数求平均值的深入讨论
对两个数求平均值可以说是初学编程的人都能很轻松的解决的问题
表面上好像是这样,但是有考虑过程序的健壮性吗?
例:
int a,b;
求a,b 的平均值
一般人很容易想的到 (a+b)/2;
可是 int取值范围是21亿多
如果
a=15000000000;
b=15000000000;//十五亿
这时候a+b会溢出?how to do it?
除法满足分配律
所以此时 int c=a/2+b/2;
完美解决溢出问题;
那么问题又来了;
a=-15000000000;
b=15000000000;
a+b=0;
如果再用 int c=a/2+b/2;
计算量就显得有些大了;
所以应当分情况讨论
a,b同号和a,b异号;
****
如何判断a,b是否同号?
有人会想到用乘法的结果和0比较;错!因为数值很大,乘法会溢出!!
最好的办法是a异或b,与原来的值仍然在同一个数量级上。
if((a^b)<0){
c=(a+b)/2;
}
else{
c=a/2+b/2;
//c=a+(b-a)/2;
}
=================
上面的代码健壮性有了,但仍非最简的
因为除2即右移1位;
并且if语句段的功能可以用三目运算符实现
c=a^b>0?a/2+b/2:a+b>>1;
或者
c=a^b<0?a+b>>1:a+(b-a)/2;//b>a情况下;
一行代码搞定即可。