Well first of all the parameters inside the formula would have to be swapped.
With a little bit of help from this link and code I came to the following routine/solution which is very close, but "ofcourse" not 100% the same.
https://www.gamedev.net/forums/topic/337531-integer-interpolation/3198110/
and the code from DavW:
// slow division example:
inline int interpolate(int a, int b, int percentage) { return (a*percentage)/100+(b*(100-percentage)/100);}
// fast shifting example:
// Revised version (position is between 0 and 256):
inline int interpolate(int a, int b, int position) { return (a * position) >> 8 + (b * (256-position)) >> 8;}
Converted to Delphi and modified/adjusted/swapped around for my purposes:
function Linear_InterpolateFast( Left, Right, Intermediate, Shift : Integer ) : integer;
var
check_x,
check_a,
check_b,
check_compare : double;
begin
// good:
result :=
// (left * ( (1 shl shift)-Intermediate)) shr shift +
// (right * Intermediate) shr shift;
// can be written as and is also more accurate:
(
(left * ( (1 shl shift)-Intermediate)) +
(right * Intermediate)
)
shr shift;
// but still not as accurate as this, some combinations are not the same:
check_x := Intermediate / (1 shl shift);
check_a := left;
check_b := right;
check_compare := check_a*(1-check_x) + check_b*check_x;
if round(check_compare) <> result then
begin
result := 0; // error detected
end;
end;
Question is can you do better, speed-wise, or accuracy-wise maintaining the speed of this function ?
Have not benchmarked anything, but my main concern is avoiding the expensive division: Intermediate/31 which is now avoided with this routine above.
The check stuff is to compared against doubles.
Bye for now,
Skybuck.
P.S.: Sorry for sloppy Delphi code, could have written it a bit better, but I've been busy all day.