Search code examples
calgorithmembeddedinterpolationlinear-interpolation

Floating point linear interpolation


To do a linear interpolation between two variables a and b given a fraction f, I'm currently using this code:

float lerp(float a, float b, float f) 
{
    return (a * (1.0 - f)) + (b * f);
}

I think there's probably a more efficient way of doing it. I'm using a microcontroller without an FPU, so floating point operations are done in software. They are reasonably fast, but it's still something like 100 cycles to add or multiply.

Any suggestions?

n.b. for the sake of clarity in the equation in the code above, we can omit specifying 1.0 as an explicit floating-point literal.


Solution

  • As Jason C points out in the comments, the version you posted is most likely the best choice, due to its superior precision near the edge cases:

    float lerp(float a, float b, float f)
    {
        return a * (1.0 - f) + (b * f);
    }
    

    If we disregard from precision for a while, we can simplify the expression as follows:

        a(1 − f) × (ba)
     = aaf + bf
     = a + f(ba)

    Which means we could write it like this:

    float lerp(float a, float b, float f)
    {
        return a + f * (b - a);
    }
    

    In this version we've gotten rid of one multiplication, but lost some precision.