Я написал базовый вариант синусоидальной функции с фиксированной точкой, который использует справочную таблицу (нацеленный на микроконтроллер AVR без FPU). Моя реализация также принимает отрицательные значения и значения, превышающие 2π, как это делает подвеска с плавающей запятой в math.h.
Поэтому мне нужно сопоставить заданное значение с диапазоном от 0 до 2π (т. е. с их аналогами с фиксированной точкой). Положительные аргументы легко обрезать с помощью встроенного в C оператора остатка %. Поскольку это не вариант для отрицательных значений, я использую следующий (очевидный) подход:
unsigned int modulus = (a - (INT_FLOOR(a / b) * b) + b) % b;
a и b являются значениями целочисленного типа, а INT_FLOOR() просто означает, что дробная часть (a/b) усекается. Эта формула гарантирует, что вычисляемый модуль (который используется в качестве индекса для массива таблиц) всегда положителен, а отрицательные аргументы сопоставляются с их положительными аналогами (сохраняя фазовые сдвиги в обоих направлениях).
Моя проблема с этим подходом заключается в том, что он кажется слишком сложным, поскольку включает не менее пяти арифметических операций. Есть ли более эффективный подход, который мне не хватает?
sin(-x) = -sin(x)
косинус четный,cos(-x) = cos(x)
. Это должно упростить дело. - person Daniel Fischer   schedule 04.05.2012fmod
для выполнения оставшихся чисел с плавающей запятой? Он корректно работает как с отрицательными числами, так и с положительными. - person Sergey Kalinichenko   schedule 04.05.2012unsigned in modulus = abs(a) % abs(b);
Альтернативно, что-то вроде:modulus = a % b; if (modulus < 0) modulus += b;
- person Jerry Coffin   schedule 04.05.2012