我对如何处理一些定点计算有疑问。我不知道如何解决。我知道浮点运算很容易,但是我想弄清楚固定点的运算方法。

我有一个定点系统,在该系统上我对信号(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,正好在信号范围内。

如果我尝试用Q格式表示值2.8928,可以说Q12。该值更改为11849。现在10 ^ 11849导致溢出。

一个人应该如何处理这些大数目?我可以使用其他格式,例如Q4,但是即使这样,数字也会变得很大,而我却变得很差。我非常希望能够以.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

有任何想法吗?

最佳答案

“如果我尝试用Q格式表示值2.8928,可以说Q12。该值更改为11849。现在10 ^ 11849导致溢出。”

混合数学很难,看来应该避免使用。您想要的是pow(Q12(10.0), Q12(2.8928))或可能是优化的pow10(Q12(2.8928))。首先,请参见my previous answer。后者可以通过硬编码的功率表进行优化。 pow10(2.8928)当然是pow10(2) * pow10(.5) * pow10(.25) * pow10(.125) * ...-2.8928的二进制表示形式中的每个1对应于一个表条目。您可能需要计算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而不是MSB开始评估exp。在上移至pow10(0.5)时,您需要重复移动中间结果,但有一半的时间可以将其与Q12乘法固有的>>12合并。

关于c++ - 定点电源功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58389261/

10-11 18:25