定点:out_Q15 = antilog(in_Q25)计算,避免溢出?

时间:2017-02-01 10:50:56

标签: c signal-processing fixed-point

我正在使用第三方定点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输入值不知何故?

1 个答案:

答案 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.000scalefactor = 2等相同的结果。这个想法就在那里。