我正在使用第三方定点antilog()
函数从分贝out_mag = 10^( in_db/20 )
计算幅度。 antilog()
采用Q6.25
格式作为输入,并在输出中提供Q16.15
。
问题是antilog()
快速溢出一些更高的dB值,如100 dB:10^( 100/20 ) = 100000
。最高价格Q16.15
格式可以为2^16-1=65535
,因此100000
不适合。
有避免溢出的技巧吗? Prescale输入值不知何故?
答案 0 :(得分:0)
我设法找到了解决方案。这有点棘手。
首先,需要一个保存输出结果的结构:
typedef struct
{
q15 v; // Value (within the [MIN, MAX] range for Q16.15).
int32 s; // Scalefactor.
} q15_t;
我们的想法是使用Scalefactor将结果作为输出提供,其中
Output = 10^y
Scale = 2^scalefactor
最终输出Output
左移scalefactor
次。
这是数学。
输入Q31格式是dB值,缩放为[-1,1],刻度为2 ^ scalefactor。 我们需要计算:
Out = 10^(2^scalefactor * in/20.0)
= 10^(p+y) // rewriting as sum
= 10^p * 10^y // to enable exponent multiplication
= 2^scalefactor * 10^y // making it power of 2 to be able to just shift
这样我们不受Q16.15最大值的限制。
我们已经知道2^scalefactor
,但需要找到y
:
2^scalefactor * in = p + y
10^p = 2^scalefactor => p = scalefactor*log(2) // rewrite as power of 2
2^scalefactor * in = scalefactor*log(2) + y // replace p
y = 2^scalefactor*in - scalefactor*log(2) // and find y
计算y,并将其输入antilog
。
如果输入为100 dB
,则输出幅度应为100.000
,这不符合Q16.15
格式。使用上述解决方案Output = 50.000
(这适用于Q16.15
!)和scalefactor = 1
,意味着最终输出50.000
转移到左1
位置。这将100.000
作为最终结果。根据您的实施情况,您可能会得到25.000
与scalefactor = 2
等相同的结果。这个想法就在那里。