5

固定小数点数の乗算問題を解こうとしています。数値は 32 ビットです。私のアーキテクチャは 8 ビットです。だからここに行きます:

  1. 私は 8.8 表記を使用しています。つまり、整数には 8、小数には 8 です。

  2. 私は10.468であるA78を持っています。その 2 の補数を取ると、答えは FFFFF588 で、これを F588 として 16 ビットに切り捨てて格納します。理由は、2 つの 2 バイト数だけを掛けたいからです。

  3. この F588 (負の 10.42 または 0x0A78) に 0x00B5 (0.707) の 2 の補数である 0xFF4B を掛けると、答えは 0x0766 になります。またはそのようなもの。

一方、私が得たのは66D8です。

B5 の負数を 32 ビットの 2 の補数で格納すると、0xFF5266D8 が得られ、これを右に 8 ビットシフトし、切り捨てて 16 ビットにすると、答えは 0x5266 になります。

一方、代わりに負の 10.42 を 32 ビットで格納すると、0xF58F66D8 が得られます。これは、8 ビットをシフトして切り捨てた後、8F66 になります。

しかし、両方の数値を 32 ビット形式で保存すると、シフトと切り捨ての後で正しい結果 (0x0766) が得られます。

なぜこうなった?32 ビットから 16 ビットに移行すると情報の損失が本質的に発生することは理解していますが、0x07 は 0x55 とは大きく異なります。私は応答に絶対に感謝します。

4

1 に答える 1

4

整数表現だけを見てみましょう。2 つの 16 ビット整数xyがあり、それらの 16 ビットの 2 の補数を形成します。ただし、これらの 16 ビットの補数は 32 ビット オブジェクトに保持します。32 ビットでは、65536–<em>x と 65536–<em>y になります。(たとえば、0xa78 で開始し、それを補完して 0xfffff588 を作成し、ビットを破棄して 0xf588 を取得します。これは、0x10000-0xa78 に相当します。)

これらを乗算すると、結果は 65536•65536 – 65536•<em>x – 65536•<em>y + x •<i>y になります。

65536•65536 は 2 32であるため、2 32を法として符号なし 32 ビット演算が実行されるため、これは消えます。– 65536•<em>x – 65536•<em>y + x •<i>y が残ります。

x •<i>y は 2 つの 16 ビット値の積であるため、32 ビットの上位 16 ビットに流れ込みます。そこにはまだ – 65536•<em>x – 65536•<em>y がありますが、これは望ましくありません。

これを行う簡単な方法は、補数の 32 ビットすべてを保持する乗算です。たとえば、0xa78 の 2 の補数を取ると、0xfffff588 になります。次に、上位ビットを破棄し、0xf588 のみを保持しました。そうしないと、0xfffff588 に 0xffffff4b を乗算し、積は 0x766d8 になり、分数をシフトすると、必要な結果である 0x766 になります。

2 の補数を 16 ビット オブジェクトに格納したために上位ビットが失われた場合は、オブジェクトをリロードするときに、符号ビットを拡張して単純に復元します。つまり、ビット 15 を取り、それをビット 16 から 31 で繰り返します。これを行う簡単な方法は、16 ビット オブジェクトを 16 ビット符号付き整数にロードし、次に 16 ビット符号付き整数を符号なし 32-ビット整数。

于 2013-01-23T21:02:59.683 に答える