Adds the lerp function as specified in P0811R3.
I don't think the special conditions are necessary, but if they are, I can add them (from the sample implementation).
Differential D60371
Add lerp function to cmath (P0811R3) zoecarver on Apr 6 2019, 5:39 PM. Authored by
Details
Adds the lerp function as specified in P0811R3. I don't think the special conditions are necessary, but if they are, I can add them (from the sample implementation).
Diff Detail Event TimelineComment Actions As mentioned in https://math.stackexchange.com/questions/907327/accurate-floating-point-linear-interpolation, given double a = 4000; double b = a; double t = 0x1.b2f3db7800a39p-2; ((1 - t) * a + t * b) != a. This does not conform to the requirement "If isfinite(t) && a == b, then r == a." Comment Actions This is too simplistic. I have a better implementation of this; but I need more tests for the denormalized cases. Comment Actions The paper suggests an implementation like this: constexpr Float lerp(Float a, Float b, Float t) { // Exact, monotonic, bounded, determinate, and (for a=b=0) consistent: if(a<=0 && b>=0 || a>=0 && b<=0) return t*b + (1-t)*a; if(t==1) return b; // exact // Exact at t=0, monotonic except near t=1, // bounded, determinate, and consistent: const Float x = a + t*(b-a); return t>1 == b>a ? max(b,x) : min(b,x); // monotonic near t=1 } I've tested this, and it works "pretty well", but not (I think) well enough. Comment Actions @cpplearner that link is very helpful. In the first answer, there is a suggested function which might work well (though I haven't had time to test it yet). It is similar to the suggested implementation. There is one case which this function does not work for, but we could add a case for that. In pseudocode: if (t < 0.5) a + (b - a) * t else b - (b - a) * (1 - t) Additionally, the link has a lot of good exceptions which we could add to our tests. How does this compare to what you have @mclow.lists? I am going to add some tests to this patch in the meantime, mind sharing what you have so far? |