Функция мощности с фиксированной точкой - PullRequest
0 голосов
/ 15 октября 2019

У меня есть вопрос относительно того, как обрабатывать некоторые вычисления с фиксированной точкой. Я не могу понять, как это решить. Я знаю, что это легко с плавающей запятой, но я хочу выяснить, как это сделать с фиксированной запятой.

У меня есть система с фиксированной запятой, где я выполняю следующее уравнение для сигнала (vSignal):

Signal_amplified = vSignal * 10^Exp

Максимальная амплитуда vSignal составляет около 4e + 05,

Система позволяет отображать сигналы 2,1475e + 09 (32 бита). Таким образом, для Signal_amplified есть некоторый запас.

По причине простоты, просто предположим, что значение Exp может быть от 0 до 10.

Допустим, первое значение равно 2.8928. Это значение хорошо работает при расчете с плавающей запятой, так как выражение 10 ^ 2.8928 приводит к 781. При использовании округленного значения с плавающей запятой 781 я получаю амплитуды сигнала 3,0085e + 08, хорошо в пределах диапазона сигнала.

Если я попытаюсь представить значение 2.8928 в формате Q, скажем, Q12. Значение меняется на 11849. Теперь 10 ^ 11849 приводит к переполнению.

Как справиться с этими большими числами ?? Я мог бы использовать другое форматирование, такое как Q4, но даже тогда цифры становятся очень большими, а мое становится бедным. Я бы очень хотел иметь возможность вычислять с точностью до 0,001, но я просто вижу, как это сделать.

Минимальный рабочий пример:

int vSignal = 400000

// Floatingpoint -> Goes well
double dExp = 2.89285
double dSignal_amplified = vSignal * std::pow(10,dExp)

// Fixedpoint -> Overflow
int iExp = 11848 // Q12 format
int iSignal_amplified = vSignal * std::pow(10,iExp)
iSignal_amplified =  iSignal_amplified>>12

Есть идеи?

Ответы [ 2 ]

1 голос
/ 15 октября 2019

"Если я попытаюсь представить значение 2.8928 в формате Q, скажем, Q12. Значение изменится на 11849. Теперь 10 ^ 11849 приводит к переполнению.".

Довольно смешанная математикатрудно, и, похоже, вы должны избегать этого. То, что вы хотите, это pow(Q12(10.0), Q12(2.8928)) или, возможно, оптимизированный pow10(Q12(2.8928)). Для первого см. мой предыдущий ответ . Последнее может быть оптимизировано жестко закодированной таблицей полномочий. pow10(2.8928), конечно, pow10(2) * pow10(.5) * pow10(.25) * pow10(.125) * ... - каждый 1 в двоичном представлении 2.8928 соответствует одной записи таблицы. Возможно, вы захотите вычислить промежуточные результаты в Q19.44 и отбросить 32 младших бита при возврате ..

Редактировать: Точность

Сохранение всех значений от pow10(2^-n) до n =12 имеет небольшую проблему в том, что результат близок к 1, а именно 1.000562312. Если вы сохраните это как Q12, вы потеряете точность при округлении. Вместо этого может быть целесообразно сохранить значение pow10(2^-12) как Q24, значение pow10(2^-121) как Q23 и т. Д. Теперь оцените Q12 pow10(Q12 exp), начиная с LSB exp, а не MSB. Вам нужно многократно сдвигать промежуточные результаты по мере продвижения до pow10(0.5), но половину времени вы можете объединить это с >>12, которое присуще умножению Q12.

1 голос
/ 15 октября 2019

Вот предложение. Это просто грубая идея, которую нужно скорректировать и уточнить.

Скажем, вам нужна точность 0.01 (вы можете выбрать нужную точность, конечно), которую вы можете представить как: Exp = N + M*10^-1 + P*10^-2где N, M и P - целые числа, а M и P - от 0 до 9.

Затем вы предварительно вычисляете и округляете все значения для 10^(M*10^-1) * 100 и 10^(P*10^-2) * 100. Все они находятся в диапазоне от 1 до 1000. Храните их в справочной таблице, чтобы избежать вычислений с плавающей запятой во время выполнения. Давайте назовем эти таблицы поиска A [M] и B [P].

Затем вы можете вычислить 10^Exp =( 10^N * A[M] * B[P] ) / 10000

Умножение не должно переполняться, поскольку A[M] * B[P] находится в диапазоне от 1 до 1 000 000, а A меньше 10 в соответствии с тем, что вы сказали.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...