我正在使用英飞凌的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
答案 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