2

これだけ仮定してください:
私は16.16固定点システムを使用しています。
システムは32ビットです。
CPUには浮動小数点プロセッサがありません。
1.0 * 0.4999より大きい値の乗算では、オーバーフローが非常に差し迫っています。

最後にもう1つ仮定します...私が作業している値は、この操作でオーバーフローを引き起こすほど高くはないとしましょう...

//assume that in practical application
//this assignment wouldn't be here as 2 fixed values would already exist...
fixed1 = (int)(1.2341 * 65536);
fixed2 = (int)(0.7854 * 65536);

mask1 = fixed1 & 0xFF; //mask off lower 8 bits

fixed1 >>= 8; //keep upper 24 bits... assume value here isn't too large...

answer = (((fixed2 * fixed1) >> 8) + ((fixed2 * mask1) >> 16));

だから問題は...これは天才のストローク(まだ考えられていないことは言うまでもありません)ですか、それとも完全な時間の無駄ですか?

4

1 に答える 1

1

再編集-私が間違っていたので:)

追加の変数を使用してより高い精度を取得しようとしているように見えますか?

実際に精度を上げようとしている場合、これは機能しますが、8ビットだけでなくint全体を使用してみませんか?

さて、あなたのコメントから、あなたは32ビットプロセッサで64ビット精度のmulsを実行する方法を知りたいと思いました。最も簡単な方法は、下にあるプロセッサに長い乗算演算がある場合です。それがARMの場合、運が良ければ、長い間使用してmulを実行し、範囲外の下位ビットをシフトして実行できます。

そうでない場合でも、long long乗算を実行して、オーバーフローの処理をコンパイラーライターに任せることができます。これらは最も簡単な方法です。

それができない場合は、4つの16ビット乗算と一連の加算およびシフトを実行できます。


// The idea is to break the 32-bit multiply into 4 16-bit 
parts to prevent any overflow.  You can break any 
multiply into factors and additions (all math here is unsigned):
      (ahi16)(alo16)
X     (bhi16)(blo16)
--------------------
      (blo16)(alo16)  - First  32-bit product var
  (blo16)(ahi16)<<16  - Second 32-bit product var (Don't shift here)
  (bhi16)(alo16)<<16  - Third  32-bit product var (Don't shift here)
+ (bhi16)(ahi16)<<32  - Forth  32-bit product var (Don't shift here)
--------------------
Final Value.  Here we add using add and add 
with carry techniques to allow overflow.

基本的に、低製品と高製品があります。低製品には最初の部分製品が割り当てられます。次に、16をシフトアップした2つの中間製品を追加します。オーバーフローごとに、上位製品に1を追加して続行します。次に、各中間積の上位16ビットを上位積に追加します。最後に、最後の製品をそのままハイ製品に追加します。

お尻に大きな痛みがありますが、それは値の任意の精度で機能します。

于 2010-05-26T15:36:22.037 に答える