Reputation: 75
I have to report average value of incoming numbers, how i could do that without using some sort of data structure to keep track of all values and then calculating average by summing them and dividing by number of values?
Upvotes: 0
Views: 260
Reputation: 1721
Keep the current sum and count. Update both on every incoming number.
avg = sum / count.
Upvotes: 1
Reputation: 11562
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?
Upvotes: 0
Reputation: 43477
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:
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))
Upvotes: 1
Reputation: 11513
If I'm not totally mistaken, one could calculate the avg(n+1)
also this way:
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
. Depending on how high n
will get and how big your values are, this could reduce rounding errors...
EDIT: Of course you have to calculate n/(n+1)
using floats, otherwise it will always render 0...
Upvotes: 1
Reputation: 55434
Just keep running sum and how many numbers you have received, that's all you need to compute the average.
Upvotes: 1