Skip to content

Instantly share code, notes, and snippets.

@bmccormack
Created March 31, 2015 01:05
Show Gist options
  • Save bmccormack/d12f4bf0c96423d03f82 to your computer and use it in GitHub Desktop.
Save bmccormack/d12f4bf0c96423d03f82 to your computer and use it in GitHub Desktop.
Moving average example in C
#include <stdio.h>
int movingAvg(int *ptrArrNumbers, long *ptrSum, int pos, int len, int nextNum)
{
//Subtract the oldest number from the prev sum, add the new number
*ptrSum = *ptrSum - ptrArrNumbers[pos] + nextNum;
//Assign the nextNum to the position in the array
ptrArrNumbers[pos] = nextNum;
//return the average
return *ptrSum / len;
}
int main(int argc, char *argv[])
{
// a sample array of numbers. The represent "readings" from a sensor over time
int sample[] = {50, 10, 20, 18, 20, 100, 18, 10, 13, 500, 50, 40, 10};
// the size of this array represents how many numbers will be used
// to calculate the average
int arrNumbers[5] = {0};
int pos = 0;
int newAvg = 0;
long sum = 0;
int len = sizeof(arrNumbers) / sizeof(int);
int count = sizeof(sample) / sizeof(int);
for(int i = 0; i < count; i++){
newAvg = movingAvg(arrNumbers, &sum, pos, len, sample[i]);
printf("The new average is %d\n", newAvg);
pos++;
if (pos >= len){
pos = 0;
}
}
return 0;
}
@sabrinnanguyen
Copy link

wow u saved my life and my grade ily

@basikv
Copy link

basikv commented Mar 30, 2022

in the above code instant of this sample array
int sample[] = {50, 10, 20, 18, 20, 100, 18, 10, 13, 500, 50, 40, 10};
can we use a sensor input for continuous signal output , for example
const int analog_pin = A0;
if i need a program for continuous sensor input what changes i need to do in this code. can someone help me with that?

@spaceMan00
Copy link

Thank you for this implementation and for all the comments. Very helpful!
I rewrote the moving average using a struct.

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


typedef struct moving_average
{
    long sum;
    int pos;
    int * buffer;
    int length;
    bool is_filled;
}moving_average_t;

int movingAvg(moving_average_t * av_obj, int new_element)
{
  //Subtract the oldest number from the prev sum, add the new number
  av_obj->sum = av_obj->sum - av_obj->buffer[av_obj->pos] + new_element;
  //Assign the nextNum to the position in the array
  av_obj->buffer[av_obj->pos] = new_element;
  //Increment position internaly
  av_obj->pos++;
  if (av_obj->pos >= av_obj->length){
    av_obj->pos = 0;
    av_obj->is_filled = true;
  }
  printf("is_filled %d", av_obj->is_filled);
  //return the average
  return av_obj->sum / (av_obj->is_filled ? av_obj->length:av_obj->pos);
}

moving_average_t * allocate_moving_average(int len)
{
    moving_average_t * av_obj = malloc(sizeof(moving_average_t));
    av_obj->sum       = 0;
    av_obj->pos       = 0;
    av_obj->length    = len;
    av_obj->is_filled = false;
    av_obj->buffer = malloc(len * sizeof(int));
    return av_obj;
}

void free_moving_average(moving_average_t * av_obj)
{
    free(av_obj->buffer);
    av_obj->buffer = NULL;
    free(av_obj);
}

int main()
{
    // a sample array of numbers. The represent "readings" from a sensor over time
    int sample[] = {50, 10, 20, 18, 20, 100, 18, 10, 13, 500, 50, 40, 10};
    // the size of this array represents how many numbers will be used
    // to calculate the average

    
    int newAvg = 0;
    int count = sizeof(sample) / sizeof(int);
    
    moving_average_t * sensor_av = allocate_moving_average(5);
    
    for(int i = 0; i < count; i++){
        newAvg = movingAvg(sensor_av, sample[i]);
        printf("The new average is %d\n", newAvg);
    }
    
    free_moving_average(sensor_av);
    sensor_av = NULL;

    return 0;
}

@Technarian
Copy link

What is sizeof(int) supposed to be the size of? "int" is a type. I am confused as to what needs to be in that field.
Thank you

@Thor-x86
Copy link

Thor-x86 commented Feb 9, 2024

What is sizeof(int) supposed to be the size of? "int" is a type

Depends on your targeted machine. On most PC, it's 4 bytes. However, other targets like Arduino Uno only have 2 bytes. So it's safer to write sizeof(int) rather than directly write 4.

For anyone who didn't familiar with C, this line

int count = sizeof(sample) / sizeof(int);

Counts how many elements in sample array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment