不使用(a + b) / 2这种方式,求两个数的平均值

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sillyxue/article/details/80508681

题目:不使用(a + b) / 2这种方式,求两个数的平均值。

我对题目的第一种理解:

(a=b)/2这种方式求平均数时,假如两个数过大的话极易发生溢出现象,通过其他的计算方式避免这种情况。
我们一般都会通过这种方式来避免溢出:

代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    scanf("%d%d", &num1, &num2);
    int avg = num1 - (num1 - num2) / 2;
    printf("%d", avg);
    system("pause");
    return 0;
}

我对题目的第二种理解:

不使用加法(+)运算符、除法运算符(/)来实现求平均数的功能。
这就需要对二进制数进行分析,找出规律,完成计算。
①第一步:用add函数 实现加法(代码见下方)

若上图所示,我们以5+6为例,先写出它们的二进制。
因为(0+1、1+0)两种情况加法不需要进位,(1+1)这种情况需要进位,所以两者二进制数相加的规律不同,需要分别计算再相加。
具体计算步骤:
通过两数的异或(^)运算,将不需要进位的(0+1、1+0)两种情况的实现相加,存于x;通过两数的与(&)运算、左移一位(<<1)作为进位数字,存于y,实现(1+1)这种情况的相加;再将这两种情况用上面的方法实现加法,用一个循环体……直到进位数字为0,这时x的值即为两数之和。

②第二步:用avg函数 实现求平均值(代码见下方)

如上图所示,我们一以5和3为例,先写出它们的二进制。
因为(1、0 和 0、1)两种情况求平均值需要右移一位实现÷2(因为“二进制右移一位相当于除以2”);而(1、1)这种情况平均值为1,还在原位,不需要移位。规律不同,所以需要分开计算再相加。
具体计算步骤:
先通过两数的异或(^)运算、右移一位(>>1)实现(1、0 和 0、1)这两种情况的求平均值;再通过两数的与(&)运算,实现(1、1)这种情况的求平均值;最后将两者分别求得的平均值相加(调用上面的add函数),返回最后的值。

③第三步:在主函数中调用avg函数 实现求平均值

完整代码:

#include <stdio.h>
#include <stdlib.h>
int add(int x, int y)//①用来实现加法的函数
{
    int tmp = 0;
    do
    {
        tmp = x^y;
        y = x&y;
        x = tmp;
        y <<= 1;//进位
    } while (y != 0);
    return x;
}

int avg(int x,int y)//②用来求平均值的函数
{
    return add(((x^y) >> 1), x&y);
}

int main()//主函数
{
    int a = 0;
    int b = 0;
    printf("Input two number:");
    scanf("%d%d",&a,&b);
    printf("%d\n",avg(a,b));

    system("pause");
    return 0;
}
展开阅读全文

没有更多推荐了,返回首页