C# 平均增加的变量数

C# 平均增加的变量数,c#,numbers,average,C#,Numbers,Average,我必须报告传入数字的平均值,我如何才能做到这一点,而不使用某种数据结构来跟踪所有值,然后通过求和并除以值的数量来计算平均值?保持当前的总和和计数。在每个传入号码上更新这两个 avg = sum / count. 保持当前的总和并计数。在每个传入号码上更新这两个 avg = sum / count. 只要运行sum和你收到的数字,这就是你需要计算平均值的全部。只要运行sum和你收到的数字,这就是你需要计算平均值的全部。如果你有数字a[1]a[2]。。。a[n]你知道他们的平均值是avg(n)=

我必须报告传入数字的平均值,我如何才能做到这一点,而不使用某种数据结构来跟踪所有值,然后通过求和并除以值的数量来计算平均值?

保持当前的总和和计数。在每个传入号码上更新这两个

avg = sum / count.

保持当前的总和并计数。在每个传入号码上更新这两个

avg = sum / count.

只要运行sum和你收到的数字,这就是你需要计算平均值的全部。

只要运行sum和你收到的数字,这就是你需要计算平均值的全部。

如果你有数字
a[1]a[2]。。。a[n]
你知道他们的平均值是
avg(n)=(a[1]+…+a[n])/n
,那么当你得到另一个数字
a[n+1]
时,你可以:

avg(n+1)=(avg(n)*n+a[n+1])/(n+1)

有些浮点错误是不可避免的,但您应该对此进行测试,看看它是否足够好

为避免溢出,可以先进行除法:


avg(n+1)=(avg(n)/(n+1))*n+(a[n+1]/(n+1))
如果您有编号
a[1]a[2]。。。a[n]
你知道他们的平均值是
avg(n)=(a[1]+…+a[n])/n
,那么当你得到另一个数字
a[n+1]
时,你可以:

avg(n+1)=(avg(n)*n+a[n+1])/(n+1)

有些浮点错误是不可避免的,但您应该对此进行测试,看看它是否足够好

为避免溢出,可以先进行除法:


avg(n+1)=(avg(n)/(n+1))*n+(a[n+1]/(n+1))
如果我没有完全弄错的话,也可以这样计算
avg(n+1)

avg(n+1) = (a[1]+ ... + a[n+1]) / (n+1) = 
         = (a[1]+ ... + a[n])/(n+1)   +   a[n+1]/(n+1) = 
         = (n(a[1]+ ... + a[n])/n) / (n+1) + a[n+1]/(n+1) =
         = n*avg(n) / (n+1) + a[n+1]/(n+1) = 

         = n/(n+1) * avg(n) + a[n+1]/(n+1)
因此,将旧的平均值乘以
n/(n+1)
,然后将新元素除以
n+1
。这取决于
n
的高度和值的大小,可以减少舍入误差


编辑:当然,您必须使用浮点计算
n/(n+1)
,否则它将始终呈现0…

如果我没有完全弄错的话,您也可以通过以下方式计算
平均值(n+1)

avg(n+1) = (a[1]+ ... + a[n+1]) / (n+1) = 
         = (a[1]+ ... + a[n])/(n+1)   +   a[n+1]/(n+1) = 
         = (n(a[1]+ ... + a[n])/n) / (n+1) + a[n+1]/(n+1) =
         = n*avg(n) / (n+1) + a[n+1]/(n+1) = 

         = n/(n+1) * avg(n) + a[n+1]/(n+1)
因此,将旧的平均值乘以
n/(n+1)
,然后将新元素除以
n+1
。这取决于
n
的高度和值的大小,可以减少舍入误差


编辑:当然您必须使用浮点计算
n/(n+1)
,否则它将始终呈现0…

您不需要跟踪总和,只需计数器:

class Averager {
   float currentAverage;
   size_t count;
   float addData (float value) {
       this->currentAverage += (value - this->currentAverage) / ++count;
       return this->currentAverage;
   }
}

从->

您不需要跟踪总数,只需计数器:

class Averager {
   float currentAverage;
   size_t count;
   float addData (float value) {
       this->currentAverage += (value - this->currentAverage) / ++count;
       return this->currentAverage;
   }
}

from->

这可能是一个简单的解决方案,但我不能使用这个简单的方法,因为浮点数的精度有限-我每秒都有大量的数字传入,所以求和会变得非常大,并且会出现一些浮点错误…@Oscar:那么,你应该在问题中指定这个限制。就目前而言,你的问题并不复杂@丹:这是一个众所周知的浮点数求平均的问题,当你对大量的数字求和时应该经常考虑。你也可以保持当前的平均值和计数,然后做新的平均值=(旧的平均值*旧的计数+传入)/(旧的计数+1)@ob1:所以你做的完全一样,只要加上一个乘法,这可能是一个简单的解决方案,但是我不能使用这个简单的方法,因为浮点数的精度有限-我每秒都有大量的数字传入,所以求和会变成非常大的数字,并且会出现一些浮点数错误…@Oscar:那么,你应该在你的问题中指定这个限制。就目前而言,你的问题并不复杂@丹:这是一个众所周知的浮点数求平均的问题,当你对大量的数字求和时应该经常考虑。你也可以保持当前的平均值和计数,然后做新的平均值=(旧的平均值*旧的计数+传入)/(旧的计数+1)@ob1:所以你做的完全一样,只是增加了一个乘法。