如何将数字转换为Q格式

时间:2017-07-06 04:09:02

标签: c embedded

我正在使用英飞凌的XMC1300 MCU系列。对于我的应用程序,我需要找出一些数据的平方根。

以下是英飞凌提供的数学库api

int16_t XMC_MATH_CORDIC_Q15_Sqrt(int16_t x) 
int32_t XMC_MATH_CORDIC_Q31_Sqrt(int32_t x)

这两个API接受并返回数据格式Q15和Q31,即它只能代表[-1,1]范围。

假设我想找出

的平方根
144
200
1000
34567
50000

如何更改范围[-1,1]中的这些数字。

输入和输出的标准化需要做些什么。

此致 Tinchu

2 个答案:

答案 0 :(得分:2)

您无法直接以Q15或Q31格式表示144或50000。如您所述,这些格式是-1到1之间数字的定点表示。

所以你留下的问题是一个基本的数学问题。 我们可以使用

这一事实
  

sqrt(A / B)= sqrt(A)/ sqrt(B)

让我们举例说明你的价值A = 144
将B设置为Q31除数B = 0x7FFFF = 32768

A/B = 0.00439`
Sqrt(A/B) = 0.0663 
Sqrt(B) = Sqrt(32768) = 181.02
Sqrt(A) = Sqrt(A/B)*Sqrt(B) = 0.0663 * 181.02 = 12.

如何使用Q15号码执行此操作?所有数字均按B缩放。 所以Sqrt(A / B)只是XMC_MATH_CORDIC_Q15_Sqrt(A) //=> 2172
因为0.0663 = 2172/32768。

Sqrt(B)是181.整数数学的最终结果是181 * 2172 / 32768 = 12 *

对于较大的数字,您需要使用Q31除数: 0x7fffFFFF = 2147483647

*注意:整数数学会将该答案舍入到11。如果你想要更好的舍入,你需要在进行除法之前检查第15位。

答案 1 :(得分:2)

我通常只是开发从机器转换为工程单位的公式。在这种情况下,输入和输出预计为Q15。下面我使用_eu来指定工程单位,_mu指定机器单位,使用sqrt()来指定实际的平方根。平方根的公式:

output_eu = sqrt(input_eu)

输入和输出的转换:

output_mu = (2^15)*output_eu
input_mu = (2^15)*input_eu

要获得机器单位的等效计算,请替换:

output_mu/(2^15) = sqrt(input_mu/(2^15))
output_mu = sqrt((2^15)*input_mu)

最好右移输入以优化精度,因此在144的情况下,数字可以左移7位:144 *(2 ^ 7)= 18432

所以输入基本上是Q7。

换句话说:

output_mu = sqrt((2^15)*((2^7)*input_eu))
          = (2^11)*sqrt(input_eu)

所以基本上这里的输出是Q11,可以向右移11位以得到工程单位的结果。

因此,如果您要在代码中执行此操作,可以说将值144加载到变量x中,并且我们希望将结果放入变量y:

y = x << 7;
y = XMC_MATH_CORDIC_Q15_Sqrt(y);
y >>= 11;

走过数学:

1) y = (144*(2^7)) = 18432
2) y = sqrt((2^15)*18432) = 24576
3) y = 24576/(2^11) = 12