How do I even out Infared distance sensor readings?
Averaging is a very good technique for improving noisy data, provided
you have a “nice” noise. “Nice” meaning that you never get “atypical”
data points, i.e. the error of any given data point is of the order of
the “typical” error amplitude. If you have for instance
additive white Gaussian
noise, then
it can be shown that averaging is in some way the “best” way to clean
your data.

However, if you have big sporadic errors, then averaging is not a good
solution. This is because you will have to average a lot of samples
in order to smoothen out a single big error... and the more samples you
average, the more chances you have to get another huge error that will
ruin your average. Of course, averaging will somewhat improve things,
and it is better than no smoothing at all, but there are better options.

The solutions to this problem lye in the realm of robust
statistics. It may look
like hairy math, but there is actually a very simple smoothing filter
that is far more robust than the average: it's called the
median. The idea is quite simple:
you sort your list of samples from smallest to largest, then you pick
the one sample that ends right in the middle of the sorted list. Unlike
the average, this filter is completely insensitive to samples carrying
huge errors, as long as the majority of samples are reasonable.

Here is an implementation of a simple moving-median filter based on the
standard libc’s qsort(). It assumes samples have int type, but you
can change it to whatever numeric type you want. You can also change the
filter length: longer lengths provide more robustness against series of
consecutive bad samples, at the cost of more filter delay, more memory,
and more processing time.

/*
 * Comparison function for qsort(): return an integer "less than, equal
 * to, or greater than zero if the first argument is considered to be
 * respectively less than, equal to, or greater than the second."
 */
int compare(const void *pa, const void *pb) {
    int a = *(int *)pa;
    int b = *(int *)pb;
    return a&lt;b ? -1 : a&gt;b ? +1 : 0;
}

#define FILTER_LENGTH 11  // length of the median filter, should be odd

/*
 * Input: raw sample.
 * Ouput: filtered sample.
 */
int median_filter(int data) {
    static int input_buffer[FILTER_LENGTH];
    static int input_index;
    int sorted_buffer[FILTER_LENGTH];

    // Store the current data point.
    input_buffer[input_index] = data;
    if (++input_index &gt;= FILTER_LENGTH) input_index = 0;

    // Sort a copy of the input buffer.
    for (int i = 0; i &lt; FILTER_LENGTH; i++)
        sorted_buffer[i] = input_buffer[i];
    qsort(sorted_buffer, FILTER_LENGTH, sizeof *sorted_buffer, compare);

    // Return median.
    return sorted_buffer[FILTER_LENGTH/2];
}


As I did not explicitly initialize the filter memory, this will output
zeros the few first times it is called. I encourage you to try this
filter and compare against an exponential moving average, and only then
decide which works best for you.