---
author:
    email: mail@petermolnar.net
    image: https://petermolnar.net/favicon.jpg
    name: Peter Molnar
    url: https://petermolnar.net
copies:
- http://web.archive.org/web/20111116141901/http://petermolnar.eu:80/sysadmin-blog/weighted-average-calculator-code-in-c/
lang: en
published: '2011-08-23T10:11:04+00:00'
summary: A short code to achieve a very fast weighted filter calculator with integers,
    using few resources.
tags:
- programming
title: weighted average calculator code in C

---

This filter was needed for a task that is polled at every 5. millisecond
during the runtime. tUI8, -16, -32 are integer types of 8, 16 and 32
bits.

``` {.c}
/* this is for a task that runs at a 5 ms frequency */
tUI8 weighted_filter(int new_sample)
{
    #define FILTER_CONST_WEIGHT                128U    /* total weights */
    #define FILTER_CONST_WEIGHT_SAMPLE        3U    /* weight of new sample */
    #define FILTER_CONST_SHIFT                8U    /* shift by */
    #define FILTER_CONST_SHIFT_VAL            256U    /* shift value */
    #define FILTER_CONST_WEIGHT_SHIFT        7U    /* shift value of weight */

    static tUI32 sample_weighted = 0U;    /* store previous weighted */
    static tBOOL sample_first_run = 1;    /* first run flag */
    tUI8 sample_output = 0;                /* return value */
    tUI32 sample_tmp = 0U;                /* temporary value, needed for calculation */

    /* if first run, set initial values to immediately reach input
     * method would be too slow without this
     */
    if (sample_first_run == 1)
    {
        sample_first_run = 0;        /* no more first runs */
        sample_output = new_sample;    /* return the input value */
        sample_weighted = (tUI32)(new_sample ) << FILTER_CONST_SHIFT;    /* weighted initial value with offset */
    }
    else
    {
        sample_tmp = new_sample;    /* add offset temperature to be in unsigned range */

        sample_tmp = sample_tmp >> FILTER_CONST_WEIGHT_SHIFT; /* divide by total weights */
        sample_tmp = (sample_weighted + (FILTER_CONST_SHIFT_VAL>>1) -1 ) >> FILTER_CONST_SHIFT;    /* round and divide by shift | need to be kept in one row! */
        sample_output = (tUI8)sample_tmp;    /* output value */
    }

return (sample_output);
}
```