У меня есть алгоритм во встроенной системе, который должен вычислять sin (theta), sin (2 * theta), sin (3 * theta) и т. Д.) С арифметикой Q15 с фиксированной точкой. грех (тета) и соз (тета) генерируются с использованием LUT/интерполяция комбы, но я использую метод Чебышева для расчета более высокий порядка SINES, который выглядит следующим образом (псевдо-код):Переполнение с использованием метода неподвижной точки Чебышева
sinN1 = Comes from Q15 LUT/interp algorithm
cosN1 = Comes from Q15 LUT/interp algorithm
sinN2 = (cosN1*sinN1)>>14;
sinN3 = (cosN1*sinN2)>>14 - sinN1;
sinN4 = (cosN1*sinN3)>>14 - sinN2;
....
Проблема в том, что при определенных условиях этот метод дает результат, который может переполнять переменную Q15. Например, давайте рассмотрим, когда тэта = 2,61697:
sinN1 (Q15) = int(2**15*sin(2.61697)) = 16413
cosN1 (Q15) = int(2**15*cos(2.61697)) = -28361
sinN2 = (-28361*16413)>>14 = -28412 # OK
sinN3 = (-28361*-28412)>>14 - 16413 = 32768 # OVERFLOW BY 1
..
Я никогда, кажется, перелива более чем МЗР или два. Кажется, это артефакт компаундирования квантования. Я использую процессор ARM Cortex M4, поэтому я могу добавить логику насыщения с относительно небольшим количеством инструкций, но я делаю много потокового DSP в реальном времени с очень низкими требованиями к задержкам, поэтому мне нужно сэкономить столько CPU, сколько я могу поэтому мне интересно, есть ли более элегантный способ справиться с этой проблемой.
Возможно, вы можете использовать арифметику без знака, так как +/- будет определяться проверкой квадрантов. Могут быть другие способы оценки функции и/или настройки коэффи- циентов. Вы не указали фактическую функцию, которая оценивается? –