任意多个数字求平均数

本文介绍了如何在不发生溢出的情况下计算大量数字的平均数。通过保持已知数字的平均值,并根据新增数字动态更新,可以避免求和过程中的溢出问题。这种方法数学上得到验证,并提供了简洁的计算代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任意多个数字求平均数

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

为了解决这个问题,我们可以这样做:
如果我们有了n个数字的平均数avg,当第n+1个数字num想要参与平均,那么在新的平均数中,avg要占n/n+1,而num则占1/n+1。所以n+1个数字的平均数为avg/(n+1)*n+num/(n+1)。
数学证明:设A为n个数字的平均值,即
A=M1+M2+..+Mnn A=\frac{M_{1}+M_{2}+..+M_{n}}{n} A=nM1+M2+..+MnB为n+1个数字的平均值
B=M1+M2+..+Mn+Mn+1n+1 B=\frac{M_{1}+M_{2}+..+M_{n}+M_{n+1}}{n+1} B=n+1M1+M2+..+Mn+Mn+1我们对第二个公式进行变换,得
B=M1+M2+..+Mnn+1+Mn+1n+1 B=\frac{M_{1}+M_{2}+..+M_{n}}{n+1}+\frac{M_{n+1}}{n+1} B=n+1M1+M2+..+Mn+n+1Mn+1=M1+M2+..+Mnn+1∗nn+Mn+1n+1 =\frac{M_{1}+M_{2}+..+M_{n}}{n+1}*\frac{n}{n}+\frac{M_{n+1}}{n+1} =n+1M1+M2+..+Mnnn+n+1Mn+1=M1+M2+..+Mnn∗nn+1+Mn+1n+1 =\frac{M_{1}+M_{2}+..+M_{n}}{n}*\frac{n}{n+1}+\frac{M_{n+1}}{n+1} =nM1+M2+..+Mnn+1n+n+1Mn+1=A∗nn+1+Mn+1n+1 =A*\frac{n}{n+1}+\frac{M_{n+1}}{n+1} =An+1n+n+1Mn+1
所以,只要我们知道了前n个数字的平均数,再知道参与平均的数字数量,那么再有更多的数字要参与平均,也不需要先求和导致溢出错误。

计算平均数的代码很简单,只有一行,其他都是测试用代码。
要注意的是,先做除法,再做乘法,可以避免乘法带来的溢出可能。

#include <stdio.h>
#include <stdlib.h>

float average(int count, float avg, int num);

int main()
{
    int i;
    int count= 0;
    float avg = 0;

    for(i = 1; i <=100; i++) {
        avg = average(count, avg, i);
        count++;
    }
    printf("The avg is %f.\n", avg);
}

// 用于计算一系列数字的平均数计算函数,优点是不用
// 计算求和,避免求和时计算溢出。
// 函数返回值为平均值计算结果,
// 输入参数中
// count为到目前为止参与平均的数字数量,
// avg为之前所有输入数字的平均数
// num为新的一个参与平均计算的数字 num为浮点数也是可以的
float average(int count, float avg, int num)
{
    return (avg/(count+1)*count + num/(count+1.0));
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值