t
、a
、b
がすべて倍精度 (IEEE Std 754) 変数であり、 、 の両方の値a
がb
NOT NaN
(ただし である可能性がある) であると仮定しますInf
。の後t = a - b
、私は必ず持っていa == b + t
ますか?
3 に答える
絶対違う。明らかなケースの 1 つはa=DBL_MAX
、b=-DBL_MAX
です。では、またt=INFINITY
そうb+t
ですINFINITY
。
さらに驚くべきことは、これがオーバーフローなしで発生する場合があることです。基本的に、それらはすべてa-b
不正確な形式です。たとえば、a
isDBL_EPSILON/4
およびb
isの場合-1
、a-b
is 1 (デフォルトの丸めモードを想定) であり、その場合a-b+b
は 0 です。
この 2 番目の例に言及する理由は、これがIEEE 演算で特定の精度に丸めを強制する標準的な方法だからです。たとえば、[0,1) の範囲の数値を強制的に 4 ビットの精度に丸めたい場合は、 を加算してから減算し0x1p49
ます。
最初の操作を実行する過程で、結果のローエンドからビットが失われた可能性があります。したがって、1つの質問は、2番目の操作でこれらの損失を正確に再現できるかどうかです。私はそれを完全には考えていません。
ただし、もちろん、最初の操作が+/-無限大にオーバーフローし、2番目の比較が等しくなくなる可能性があります。
(もちろん、一般的なケースでは、==
浮動小数点値に使用することはほとんどの場合バグです。)
フロートを使用する場合、何も保証されません。指数が両方の数値で異なる場合、算術演算の結果は float では完全に表現できない場合があります。
次のコードを検討してください。
float a = 0.003f;
float b = 10000000.0f;
float t = a - b;
float x = b + t;
Visual Studio 2010 で実行するt==-10000000.0f
と、したがってが得られますx==0
。
float を比較するときは、等値を使用しないでください。代わりに、両方の値の差の絶対値と、必要な精度に対して十分小さいイプシロン値を比較します。
浮動小数点の実装が異なると、同じ操作に対して異なる結果が返される可能性があるため、さらに奇妙になります。