lerp для целых чисел или математики с фиксированной точкой

Есть ли элегантный способ линейной интерполяции с использованием целых чисел? (Для усреднения измерений АЦП в микроконтроллере измерения АЦП являются 12-битными, микроконтроллер отлично работает с 32-битными целыми числами). Коэффициент f находится в диапазоне [0, 1].

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

person DikobrAz    schedule 04.12.2015    source источник
comment
stackoverflow.com/a/21379337/99691   -  person gordy    schedule 05.12.2015


Ответы (1)


Что ж, поскольку у вас так много дополнительных целых битов, решение с использованием целых чисел будет таким:

Используйте целое число для вашего параметра F, с F от 0 до 1024 вместо числа с плавающей запятой от 0 до 1. Тогда вы можете просто сделать:

(A*(1024-F) + B * F) >> 10

без риска переполнения.

На самом деле, если вам нужно больше разрешения в вашем параметре, вы можете выбрать максимальное значение F как любую степень 2 до 2**19 (если вы используете беззнаковые целые числа; 2**18 в противном случае).

Это не очень хорошо округляет (вместо этого оно усекает), но использует только целочисленные операции и избегает деления с помощью оператора сдвига. Для этого по-прежнему требуется целочисленное умножение, для которого у ряда MCU нет оборудования, но, надеюсь, это будет не так уж плохо.

person Gretchen    schedule 04.12.2015
comment
Являются ли A и B в этом ответе целыми числами или числами с плавающей запятой? - person jjxtra; 06.04.2017