2011-01-22 30 views
0

固定小数点15.16の乗算と除算のアルゴリズムを探しています。15.16の数値の固定小数点乗算/除算

私はすでに加減算しています。それらは簡単でした - シンプルな32ビットの加算と減算。乗算と除算では、三角関数と指数関数/ログ関数を追加することもできます。私の図書館は相反する機能を持っており、それを使って部門を実装することができます:a * (1/b) = a/b。しかし、基数を無視するので、32ビットの乗算は機能しません。

私は16ビットのマイクロコントローラで作業していますので、32ビットの乗算を避けたいと思います。これはプロセッサで約4サイクルかかります。しかし、私は浮動小数点数学を置き換えようとしています。

私は結果をシフトまたは回転する必要があると聞いたことがありますが、これがどのように役立つか、具体的にシフトする方法がわかりません。任意の提案や助けに感謝!

答えて

4

だと思うが、この方法です:あなたの番号ABは、あなたがAB * CDを掛ける場合にように、あなたが得る値は、(CD * 65536)*(AB * 65536)です

(* 65536 AB)のように表されます

ab/cdを分割すると、得られる値は(ab * 65536)/(cd * 65536)になるので、これを正しい表現に戻すには65536を掛ける必要があります。分割する前に65536を掛けて、できるだけ多くのビットを保持する必要があります。

プロセッサで高速であれば(* 65536)はもちろん(< < 16)を代用することもできます。同様に、(/ 65536)の代わりに(>> 16)を使用できます。ここで

はAB *のCDです:

uint32_t result_low = (b * d); 
uint32_t result_mid = (a * d) + (b * c); 
uint32_t result_high = (a * c); 
uint32_t result = (result_high << 16) + result_mid + (result_low >> 16) 
+0

それは確かです。私の説明はアルゴリズムであり、実装ではありません。 –

+0

マイクロチップは、PIC24およびdsPIC用の固定小数点数学ライブラリも提供しています。 http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en552208を参照してください。 –

0

乗算は、簡単に64ビット乗算で行われます。(a * b) >> 16。部門も、同様に、64ビットで簡単に行うことができます:(a << 16)/b。丸め/エラー要件に応じて、出力の最後のビットを正しく得るためには、それを少し複雑にしたいかもしれません。

+0

@ Paul R私のプロセッサでは32x32という大きな懸念はないと思います。 –

+0

@Paul R、I *は前を上にした。 –

2

まず理論:別のQ15.16でQ15.16を乗じ、符号付きの数を想定してはあなたに(15 + 15 + 1)Qを与えるだろう(16+。 16)= Q31.32の数。したがって、結果を保持するには64ビットの整数変数が必要です。

コンパイラに64ビットの整数型がある場合は、そのコンパイラを使用して、コンパイラに16ビットCPUで32ビットx 32ビット乗算を行う方法を理解させます。

int32_t a_15q16, b_15q16; 
int64_t res_31q32 = (int64_t)a_15q16 * (int64_t)b_15q16; 

その後のQ31.32の結果は、アプリケーションによって大きく異なります。

なぜ結果に30の代わりに31の整数が必要なのか疑問に思うかもしれません。実際には、-2^15に-2^15を掛ける場合にのみ追加ビットが必要です。オペランドが決して-2^15に等しくないことが保証されている場合は、Q30.32の結果を仮定することができます。

コンパイラが64ビット整数をサポートしているかどうかを調べるには、コンパイラのマニュアルを参照する必要があります。これがC99コンパイラの場合は、stdint.hヘッダーにint64_t型があるかどうかを確認してください。

関連する問題