定点电源功能

时间:2019-10-15 07:22:19

标签: c++ c signal-processing fixed-point

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

我有一个定点系统,我在该系统上对信号(vSignal)执行以下方程式:

Gson gson = new GsonBuilder().registerTypeAdapter(Article.class, new CustomDeserializer()).create();

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的精度进行计算,但是我只能看到应该怎么做。

最小工作示例:

@Expose

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是个提案。这只是一个粗略的想法,需要进行调整和完善。

假设您需要一个0.01的精度(您可以选择所需的精度),您可以将指数表示为:Exp = N + M*10^-1 + P*10^-2其中N,M和P是整数,而M和P是在0到9之间。

然后,您预先计算并舍入10^(M*10^-1) * 10010^(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。

我用几个值进行了快速测试,似乎给出了可接受的精度。

答案 1 :(得分:1)

“如果我尝试用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开始计算exp ,而不是MSB。在向上移动到pow10(0.5)时,您需要重复移动中间结果,但是有一半的时间可以将其与Q12乘法固有的>>12合并。