2017-06-18 2 views
2

浮動小数点減算では丸めが期待できません。浮動小数点の減算でも丸めを行います

IEEE754-2008、4.3.1は「roundTiesToEvenを...でも最下位桁が配信されなければならないと表現できない無限に正確な結果をブラケット最も近い2つの浮動小数点数は、均等に近い1であれば、」言う

インテルのドキュメントは、これはデフォルトのモードであると言う、より明示的に定義します。私は最初の浮動小数点加算を歩くよ

https://software.intel.com/en-us/node/503710

- 私の仮定を検証するために - 私は期待通りに動作します。次に、私の理解が崩れている箇所を示すために、テストケースを少し修正します。

さんは「binary32」形式でここに表される2つの浮動小数点数を、見てみましょう:

S Exponent  Significand 
0 10000010 00000000000000000000001 (0x41000001) 
    130 

0 01111111 00000000000000000000100 (0x3F800004) 
    127 

は私が小さい指数(第2オペランド)との数の仮数をシフトし、それらを追加するには右へ3ヶ所(私もここに暗黙のリード1を追加しました):

1.00000000000000000000001 
+ 0.00100000000000000000000 100 
---------------------------- 
    1.00100000000000000000001 

シフトアウトした値は、2(100)間の途中にあるので、それも値に合計を丸める必要があります。

バイナリで
1.00100000000000000000010 

、完全な値は次のとおりです。

0 10000010 00100000000000000000010 (0x41100002) 

私はこれを確認することができます:私は最初のオペランドに1を追加した場合

./a.out 
41100002 

#include <stdint.h> 
#include <stdio.h> 

union uval { 
    float fval; 
    int32_t ival; 
}; 

int main() 
{ 
    union uval a, b, c; 
    a.ival = 0x41000001; 
    b.ival = 0x3F800004; 
    c.fval = a.fval + b.fval; 
    printf("%08x\n", c.ival); 
} 

版画:

a.ival = 0x41000002; 

私は同じことを取得します。

./a.out 
41100002 

をこれまでのところ、とても良い:それも結果にダウンを四捨五入しています。私は元の値を使用して修正する場合は、2番目のパラメータは1に符号ビットを設定することにより、負に:私は

a.ival = 0x41000001; 
b.ival = 0xBF800004; 

を得る:

./a.out 
40E00001 

はどれ:

0 10000001 11000000000000000000001 
    129 

結果は、2番目のパラメータがアライメントされた後も、2つの値の中間になっているはずです。この場合、なぜそれは同じ値に丸められなかったのでしょうか?

+1

なぜ最終結果が正確に表現できるのではなく、その中間になると思いますか? –

+0

私はそれを整列させるときに第2オペランドから数字 '100'をシフトしたので(ソースオペランドの指数は3だけ異なります)。 – JeffB

+2

重要度の高い終わりで何が起きているのか、結果の指数が変わったのか考えましたか? –

答えて

5

最後の結果を理解するために、丸めはIEEE 754算術演算の最後のステップであることを覚えておくことが重要です。あたかも正規化によって正確に行われ、その後丸められます。

2つの計算の重要度の高い最後を見ると、両方のオペランドは明示的ビットにゼロを持ちます。 bで暗黙1ビット右指数に合わせて三箇所シフトされる:これらの追加

1.000 
0.001 

を1.001を与えるので、指数はa同じままであり、明示的な1ビットの結果です。

これらを減算すると、0.111が得られます。正規化は、これを左に1ビットシフトして先頭の0を取り除き、1.110とする。 2つの明示的な1ビットが結果に格納されます。

ここで重要度の低い終わりを見てください。生の減算は「半分の間」の位置に1ビットを残します。正規化による左シフトは、それを最下位格納ビットに変え、結果は正確である。

関連する問題