不动点:out_Q15 = antilog( in_Q25 ) 计算,避免溢出?
Fixed-point: out_Q15 = antilog( in_Q25 ) calculation, avoiding overflow?
我正在使用第 3 方定点 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
不适合。
有没有避免溢出的技巧?不知何故预分频输入值?
我设法找到了解决方案。这有点棘手。
首先,需要一个保存输出结果的结构:
typedef struct
{
q15 v; // Value (within the [MIN, MAX] range for Q16.15).
int32 s; // Scalefactor.
} q15_t;
想法是提供结果作为带有比例因子的输出,其中
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
等相同的结果。这个想法就在那里。
我正在使用第 3 方定点 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
不适合。
有没有避免溢出的技巧?不知何故预分频输入值?
我设法找到了解决方案。这有点棘手。
首先,需要一个保存输出结果的结构:
typedef struct
{
q15 v; // Value (within the [MIN, MAX] range for Q16.15).
int32 s; // Scalefactor.
} q15_t;
想法是提供结果作为带有比例因子的输出,其中
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
等相同的结果。这个想法就在那里。