stability of an exponential moving average I used the following code:

#include&lt;vector&gt;
class UltrasonicRecorder
{
public:
    UltrasonicRecorder(int referenceValue, Input referenceInput) :
        _referenceValue(referenceValue),
        _referenceInput(referenceInput)
    {}

    std::vector&lt;int&gt; GetData();

    void RecordData(Input);
    int CompensateTemperatur(int);

private:
    double _compensation;
    int _referenceValue;
    Input _referenceInput;
    std::vector&lt;int&gt; _data;
};

std::vector&lt;int&gt; UltrasonicRecorder::GetData()
{
    std::vector&lt;int&gt; ret;
    std::swap(ret, _data);

    return ret;
}

void UltrasonicRecorder::RecordData(Input input)
{
    int value = (ANALOG_VALUE_RANGE - 1) - GetAnalogValue(input);
    value = CompensateTemperature(value);
    _data.push_back(value);
}

int UltrasonicRecorder::CompensateTemperature(int value)
{
    int measuredValue = GetAnalogValue(_referenceInput);
    if(measuredValue &gt; 0)
    {
        static const double delta = 1.0e-6;
        _compensation = (1.0 - delta) * _compensation + 
            delta * _referenceValue / (double)measuredValue;
    }
    return static_cast&lt;int&gt;(value * _compensation);
}


int GetAnalogValue(Input) returns a 12 bit value from a ultrasonic sensor measuring distance (0-4095, ANALOG_VALUE_RANGE = 4096). double _compensation; is a member of the encapsulating class. _referenceValue is the initial reference value from _referenceInput (normally it has a low fluctuation, with a value somewhere in the middle of the 12 bit range, but it changes with temperature). 

RecordData() is called every 2 milliseconds (more or less, running on Windows). So a high update rate for the reference value, but I wanted a gradual compensation over time. Therefore I used an exponential moving average, the delta is empirically determined and may need to be changed later. 

GetData() is called approximately every second to flush _data and use the record for further evaluation.

We started testing this code on customer facilities, but got the feedback that values are drifting away after a few days. I think it's a numerical unstable algorithm that accumulates rounding errors. Can someone with more experience with the subtleties of floating-point arithmetic answer me:

Can this exponential moving average algorithm be improved to achieve better stability?

Notes for additional improvements of the code are welcomed as well.
How about initializing the compensation factor so that it doesn't have to do the convergence from an undefined state?

UltrasonicRecorder(int referenceValue, Input referenceInput) :
    _referenceValue(referenceValue),
    _referenceInput(referenceInput)
{
    _compensation = 1.0; // This!
}


Edit: Your EWMA is correct. Your woes of compounding errors are unfounded. As you always "move towards" the measurement value, any compounding errors will be limited. In fact the compound error will at any point in time be less than:

(sum{i=0,infty} (1-delta)^i)*ULP(ANALOG_VALUE_RANGE) ~ 2^-(52-12) / delta ~ 10^-6