2

次のアルゴリズムを使用して、32 ビット * 32 ビットの乗算を行っています。

a (32 ビット) と b (32 ビット) を両方とも符号付きで乗算するとします。

a = ah * 2^16 + al [ah - 上位 16 ビット、al - 下位 16 ビット]

b = bh * 2^16 + bl [bh - 上位 16 ビット、bl - 下位 16 ビット]

効果的に行っています

結果 = (al * bl) + (((ah * bl) + (al * bh)) * 2^16) + ((ah * bh) * 2 ^ 32) ~~~


私の質問、

これを行うためのより良い方法はありますか?

4

4 に答える 4

7

どのメインストリーム コンパイラでも、32 ビット プラットフォームでの 64 ビット int のエミュレーションは、複数ステップの計算を自分で行うのとほぼ同じくらい効率的です。しかし、それははるかに確実に正しいでしょう。

オーバーフローするのに十分な大きさの値で単純な算術演算を行う場合、私が見た中で最も高度に調整された数学ライブラリでさえ、int64 を使用しています。

于 2009-08-31T19:15:35.293 に答える
4

Google「カラツバ掛け算」。

OIh、そしてコードで、定数 2^15 (2 回表示されます) を 2^16 に変更します。

于 2009-09-04T07:24:55.627 に答える
3

答えはノーです。2^n の代わりにビット シフトとマスクを使用する以外に、より良い方法はありません。すなわち:

a * 2^n <=> a << n

第二に、あなたのintは署名されていますか、それとも署名されていませんか? それらが署名されている場合、それは状況を変えます。

第三に、あなたの 2^15 が正しいかどうかわかりません。少なくとも符号なしの場合は、ビットを 15 ではなく 16 シフトする必要があります。

最後に、下位の int での整数オーバーフローに注意する必要があります。オーバーフローする下位の整数に数値を合計すると、上位の整数を正しくインクリメントする必要があります。

于 2009-08-31T01:59:34.590 に答える
1

64 ビット値を格納する方法を知る (指定する) 必要があります。おそらく、それは 32 ビット値のペア、配列の 2 つの要素、または構造体の 2 つの要素です。また、符号情報を結果に格納する方法も考慮する必要があります。

Mechanically, you probably want to convert both signed values to unsigned, and then do the split and reassemble along the lines you showed, being careful to ensure that carries from the low order 32-bit value are managed properly in the high order 32-bit value.

Depending on your initial design decisions, you may also need to fettle the representation of the sign of the result, and maybe even all the other bits.

Similar comments apply to multiplying two 16-bit numbers without any 32-bit results, something that was once important but most people don't have to worry about.

于 2009-08-31T02:15:14.240 に答える