2017-07-06 3 views
0

私はInfineonのXMC1300 MCUシリーズを使用しています。私のアプリケーションでは、いくつかのデータの平方根を調べる必要があります。続い数値をQ形式に変換する方法

は、これら二つのAPIが受け入れるとデータフォーマットQ15及びQ31は、すなわち、それは唯一[-1,1]の範囲を表すことができる返すインフィニオン

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

によって提供される数学LIB APIです。

と仮定私は範囲でこれらの番号を変更するにはどうすればよい

144 
200 
1000 
34567 
50000 

の平方根を見つけるために望んでいた[-1、1]。

入力と出力の正規化には何が必要ですか。

よろしく、 Tinchu

+0

あなたが言及している2つの関数は、-1から1の範囲の値に対するsqure rootを決定することができ、0から50000の値の計算にそれらを使用したいですか?より理解しやすくするために、 "int"型の結果が-0.25の場合の結果を知りたいと思います。さもなければ、正規化は、既知の数の2乗で除算する(すなわち、90000または50000に近いものを除いて)、その結果に既知の数(300)を掛けることが必要です。あなたの問題の周りに少しmcveを提供すれば、私はコードで答えを出すでしょう。 – Yunnosch

+0

あなたの種類の返信のための@Yunnoschの高校 – user1093152

+0

https://www.infineonforums.com/threads/5210-Math-Cordic-Square-root-API?s=d10133f31beb6a28a7bf2efa0f2b098d – user1093152

答えて

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最終的な結果は、あなたがQ31の除数を使用する必要が多数の場合は181 * 2172/32768 = 12 *

です: 0x7fffFFFF = 2147483647

*注:整数演算は、その答えを丸めますより良い丸めが必要な場合は、分割する前にビット15を調べる必要があります。

+0

お世話になります。 – user1093152

+0

A = 144、XMC_MATH_CORDIC_Q15_Sqrt(A)// => 2172、この値の取得方法。私はAPIに144を渡しているときに3117を取得しているからです。さらに、200または1000のような他のケースを取ると、どのように動作しますか? – user1093152

+0

私はなぜあなたが3117を得ているのかわかりません。あなたは0x4000のために何を得ますか? – AShelly

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 *(2^7)= 18432

このように、精度を最適化するために入力されるので、144の場合、その数は7ビットだけシフトしたままにすることができます。

したがって入力は基本的にQ7です。言い換えれば

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

だから基本的に、ここで出力がQ11で、工学単位で結果を得るために右の11ビットをシフトすることができます。あなたは、コードでこれを実行した場合

だから、値144は、変数xにロードされると言うことができますし、我々は変数yに結果を入れたい:

1) y = (144*(2^7)) = 18432 
2) y = sqrt((2^15)*18432) = 24576 
3) y = 24576/(2^11) = 12 
:数学を歩く

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

+0

'^'は排他的論理和演算子であるため、累乗を表すためにCコード_を混同しています。ポストは、コードから数学へ/から切り替える際に明確さが欠けています。他の形式を検討してください。 – chux

+0

Jonathon、chuxさんありがとうございました。 – user1093152

+0

こちらもどうですか? output_mu = sqrt((2^15)*((2^7)* input_eu)) =(2^11)* sqrt(input_eu)。 (2^7)計算の仕方 – user1093152

関連する問題