[英]Averaging increasing number of variables
我必须报告传入数字的平均值,如何在不使用某种数据结构来跟踪所有值的情况下做到这一点,然后通过将它们求和并除以值数来计算平均值?
Keep the current sum and count. 保留当前的总和和计数。 Update both on every incoming number. 更新每个传入号码。
avg = sum / count.
只需保持累加总和以及已收到多少个数字,这就是计算平均值所需的全部。
If you have the numbers a[1] a[2] ... a[n]
and you know their average is avg(n) = (a[1] + ... + a[n]) / n
, then when you get another number a[n + 1]
you can do: 如果您有数字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)
Some floating point errors are unavoidable, but you should test this and see if it's good enough. 不可避免会出现一些浮点错误,但是您应该对此进行测试,看看它是否足够好。
To avoid overflow, you could do the division first: 为了避免溢出,您可以先进行除法:
avg(n + 1) = (avg(n) / (n + 1)) * n + (a[n + 1] / (n + 1))
If I'm not totally mistaken, one could calculate the avg(n+1)
also this way: 如果我没有完全弄错,可以这样计算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)
so multiply the old avg by n/(n+1)
and add the new element divided by n+1
. 因此,将旧平均avg乘以n/(n+1)
并添加新元素除以n+1
。 Depending on how high n
will get and how big your values are, this could reduce rounding errors... 根据将得到的n
高和您的值有多大,这可以减少舍入误差。
EDIT: Of course you have to calculate n/(n+1)
using floats, otherwise it will always render 0... 编辑:当然,您必须使用浮点数计算n/(n+1)
,否则它将始终呈现0 ...
you don't need to keep track the total sum, only counter: 您无需跟踪总金额,只需计数器:
class Averager {
float currentAverage;
size_t count;
float addData (float value) {
this->currentAverage += (value - this->currentAverage) / ++count;
return this->currentAverage;
}
}
from-> prevent long running averaging from overflow? from-> 防止长期平均溢出?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.