# Thread: Trying to calculate a running average

1. ## Trying to calculate a running average

I am trying to figure out how to keep a running average of the last 5 temps read in. I don't know how/where to reset my counter to 0 or increment it? Will something like the code below work to keep a running average of last 5 values read in?

Code:
```Average()
{
int loop_counter= 0;
while (!0)
{
Current_Temp= Get_Temp():
Temp_Array[loop_counter] = Current_Temp;

if ((loop_counter % 4) == 0)
{

Temp_Avg = Calculate_Average(Temp_Array);
loop_counter = 0;
}

loop_counter++;
}
}``` 2. Maybe something like this. Fill up a 5 element array and use its sum to calculate the average. Cycle around the elements subtracting the value at the current index from the sum and adding in the new temperature (and storing it at the current index). I just left it in an infinite loop for testing.
Code:
```#include <stdio.h>

#define NumTempsToAvg  5

double GetTemp() {
printf("temp: ");
double d = 0.0;
scanf("%lf", &d);
return d;
}

void average() {
double temps[NumTempsToAvg];
double sum = 0.0;

for (int i = 0; i < NumTempsToAvg; i++) {
temps[i] = GetTemp();
sum += temps[i];
}

for ( ; ; ) {
for (int i = 0; i < NumTempsToAvg; i++) {
printf("avg: %f\n", sum / NumTempsToAvg);
sum -= temps[i];
temps[i] = GetTemp();
sum += temps[i];
}
}
}

int main() {
average();
}``` 3. Originally Posted by john.c Maybe something like this. Fill up a 5 element array and use its sum to calculate the average. Cycle around the elements subtracting the value at the current index from the sum and adding in the new temperature (and storing it at the current index). I just left it in an infinite loop for testing.
Code:
```#include <stdio.h>

#define NumTempsToAvg  5

double GetTemp() {
printf("temp: ");
double d = 0.0;
scanf("%lf", &d);
return d;
}

void average() {
double temps[NumTempsToAvg];
double sum = 0.0;

for (int i = 0; i < NumTempsToAvg; i++) {
temps[i] = GetTemp();
sum += temps[i];
}

for ( ; ; ) {
for (int i = 0; i < NumTempsToAvg; i++) {
printf("avg: %f\n", sum / NumTempsToAvg);
sum -= temps[i];
temps[i] = GetTemp();
sum += temps[i];
}
}
}

int main() {
average();
}```
So I got a little bit more information. It should be a running average will each time a new value is read in, an average is calculated on the last 5 readings, by replacing the oldest value read in. Can you please help with this? 4. Originally Posted by knik653 So I got a little bit more information. It should be a running average will each time a new value is read in, an average is calculated on the last 5 readings, by replacing the oldest value read in. Can you please help with this?
That is, in fact, what's up there! 5. Now that I think about it, the above procedure will presumably accumulate errors. Since there's only 5 values, you could just add them all up every time. If the above procedure is used you should maybe sum the whole array every 250th (or whatever) iteration so the error doesn't get too big. 6. Doesn't a running average usually use a circular buffer? 7. Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors from the actual sum of the array (kind of a drunkards walk up and down but ultimately away from the true value). 8. Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors
So don't subtract and add, just replace the oldest value and recompute the sum and average. You're only talking about 5 numbers so the time shouldn't be an issue in most cases. 9. In this case, sure, but if you had a lot of values you might only want to recompute the true average every nth iteration. That's all I was saying. 10. Originally Posted by john.c Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors from the actual sum of the array (kind of a drunkards walk up and down but ultimately away from the true value).
But don't you have to rotate the the other values?
I having a hard time wrapping my mind around this.
I get to read in one value at a time 11. Originally Posted by knik653 But don't you have to rotate the the other values?
I having a hard time wrapping my mind around this.
I get to read in one value at a time
You could rotate the values, if you are sufficiently bored. Generally though you just keep track of where the oldest value is, and replace that value. 12. Originally Posted by tabstop You could rotate the values, if you are sufficiently bored. Generally though you just keep track of where the oldest value is, and replace that value.
Any hints on how to keep track of the oldest? 13. Originally Posted by knik653 Any hints on how to keep track of the oldest?
It starts at 0, then goes up by one each time, until you get to the end, and then it becomes zero again. 14. I having a hard time wrapping my mind around this.
Yea, doing a running average can get a little confusing. I started out creating a structure to "house" the CircularBuffer, something like:
Code:
```#define MAX_ITEMS 5

typedef struct CircularBuffer
{
int max_items;
int items[MAX_ITEMS];
int current_index;
int num_items;
} CircularBuffer;

void init_buffer(CircularBuffer* buffer);
double average(CircularBuffer* buffer, int value);```
The first function is to "initialize" the buffer to the starting values, zero for everything except max_items which should be the same as the array size, this function should be fairly easy.

The second function is where the "magic" takes place. It handles placing the "new" value into the array and modifying the current_index (insuring that this value stays within the bounds of the array) when this variable reaches the end of the array it is reset to zero to start back at the beginning of the array for the next value.

The num_items variable keeps track of how many items are actually in the array and is used to compute the average. This value will increment until it reaches the size of the array, then it stays constant.

Hopefully this gives you enough hints. 15. Originally Posted by tabstop It starts at 0, then goes up by one each time, until you get to the end, and then it becomes zero again.

This is what I need to do and I get one value at a time.

/* if first time /
* set all array values to current value
* return average equals to current value
*/

/* else
* replace the oldest array value with current value
* calculate average
*/

I really can't figure it out how to keep track of the loop counter to know what position to replace and how to reset the loop count to zero Popular pages Recent additions average, get_temp, loop_counter, read, running 