1

x固定小数点変数(2 進小数点 6 [BP6] の符号なし 16 ビット整数 [U16] 型) で係数を使用して乗算演算を実行する必要があります。係数Aは常に 0 と 1 の間であることがわかっています。コードが書き込まれています。 32 ビット組み込みプラットフォーム用の C 言語。

この係数も U16 BP6 にすると、乗算により U32 BP12 になることがわかっています。この結果を U16 BP6 に再スケーリングしたいので、最初の 10 ビットと最後の 6 ビットを切り取るだけです。

ただし、係数の精度は小数ビットの数によって制限されており、整数の完全な 10 ビットは必ずしも必要ではないため、係数変数Aを U16 BP15 にして、より正確な結果を得ることができると考えていました。

私は次の例を考え出しました(我慢してください):

それを(10進数)としましょう。x = 172.0係数(10進数)を使用したいと思いA = 0.82ます。理想的な 10 進数の結果は 172.0 * 0.82 = 141.04 です。

バイナリでは、x = 0010101100.000000.

A に BP6 を使用している場合、バイナリ表現は次のいずれかになります。

    A_1 = 0000000000.110100 = 0.8125 or
    A_2 = 0000000000.110101 = 0.828125

(値が床または天井のどちらに基づいているかによって異なります)。

x と A のいずれかの値の間で 2 進乗算を実行すると、次の結果が得られます (先頭のゼロは除外されます)。

    A_1 * x = 10001011.110000000000 = 139.75 
    A_2 * x = 10001110.011100000000 = 142.4375

どちらの場合も、最後の 6 ビットをトリミングしても結果には影響しません。

ここで、A を BP15 に拡張すると、

    A_3 = 0.110100011110110 = 0.82000732421875

結果の乗算は次のようになります

    A_3 * x = 10001101.000010101001000000000 = 141.041259765625

余分な小数部の 15 ビットをトリミングすると、結果は次のようになります。

    A_3 * x = 10001101.000010 = 141.03125

したがって、係数を拡張して小数ビットを増やすと、より正確な結果が得られることは明らかです (少なくとも私の例では)。これは一般的に成り立つものでしょうか?これは実際に使用するのに良い/悪いですか? 私は何かを見逃しているか、誤解していますか?

編集:ここでは「精度」の代わりに「精度」と言うべきでした。小数ビットを多く含む結果ではなく、期待値に近い結果を探しています。

4

1 に答える 1

1

同様のコードを実行したので、あなたがしていることは、次の懸念事項で一般的に当てはまると思います。

  1. 2 進小数点をシフトするときに予期しないオーバーフローが発生するのは非常に簡単です。厳密なテスト/分析および/またはコード検出が推奨されます。 顕著な失敗: Ariane_5

  2. あなたは精度が欲しいので、「切り落とす...最後の6」には同意しません。代わりに、処理時間が許す限り、結果を四捨五入することをお勧めします。MSBit を使用して切り取って結果を調整します。

于 2013-09-27T17:57:05.380 に答える