В качестве канонического примера рассмотрим проблему уменьшения аргумента для тригонометрических функций, как при вычислении x mod 2π в качестве первого шага вычисления sin (x). Эта проблема затруднена тем, что вы не можете просто использовать fmod
, потому что y (2π в примере) не представляется.
Я придумал простое решение, которое работает для произвольных значений y, а не только 2π, и мне любопытно, как он сравнивает (по производительности) с типичными алгоритмами сокращения аргументов.
Основная идея состоит в том, чтобы хранить таблицу, содержащую значение 2 n mod y для каждого значения n в диапазоне log2 (y), до максимально возможного показателя с плавающей запятой, а затем используя линейность модульной арифметикой, суммируйте значения в этой таблице над битами, которые установлены в значении x. Он равен N ветвям и не более N дополнений, где N - количество бит мантиссы в вашем типе с плавающей точкой. Результат не обязательно меньше y, но он ограничен N * y, и процедура может быть применена снова, чтобы дать результат, ограниченный log2 (N) * y или fmod
, можно просто использовать в этой точке с минимальным ошибка.
Можно ли улучшить это? И типичные алгоритмы сокращения тригонометрических аргументов работают для любого y или только для 2π?