Алгоритм сглаживания c использованием целочисленной арифметики

следующий код был взят из Arduino учебник по сглаживанию:

int smooth(int data, float filterVal, float smoothedVal) { 

  if (filterVal > 1) {
    filterVal = .99;
  }
  else if (filterVal <= 0) {
    filterVal = 0;
  }

  smoothedVal = (data * (1 - filterVal)) + (smoothedVal  *  filterVal);

  return (int)smoothedVal;
}

следующее утверждение, взятое из того же учебника, заставило меня задуматься:

эта функция может быть легко переписана с помощью all-integer math, если вам нужна большая скорость или вы хотите избежать поплавков.

факт в том, что я хочу избежать поплавков и увеличить скорость, но мне интересно: как преобразовать это в целочисленную арифметику? Немного стучать решения бонус ;о)

1 ответов


простой метод масштабирования путем умножения входного значения, например 10000 и положить этот результат в int выполните вычисления в int, а затем масштабируйте вывод обратно в float путем делить с таким же фактором.

в вашей функции вам также нужно масштабировать все с тем же фактором.

выбор фактора зависит от возможных диапазонов значений; вы хотите избежать переполнения на верхнем конце и неточности на нижний конец. Если вы подумаете об этом, фактор определяет, где вы ставите десятичную точку: фиксированная точка, а не плавающая точка.

фактор может быть чем угодно, он не должен быть 100, 1000 и так далее, но 627 тоже нормально.

если вы идете по этому маршруту, вы хотите преобразовать столько кода в int, потому что преобразования, описанные выше, конечно, также требуют времени.

чтобы проиллюстрировать мою точку зрения, следующее Может быть это:

#define FACTOR 10000  // Example value.
int smooth(int data, int filterVal, int smoothedVal)
{ 
    if (filterVal > FACTOR)
    {
        filterVal = FACTOR - 100;
    }
    else if (filterVal <= 0)
    {
        filterVal = 0;
    }

    smoothedVal = (data * (FACTOR - filterVal)) + (smoothedVal * filterVal);

    return smoothedVal;
}

вам может понадобиться / хотите проверить переполнение,...