t、a、bがすべて倍精度 (IEEE Std 754) 変数であり、 、 の両方の値aがbNOT NaN(ただし である可能性がある) であると仮定しますInf。の後t = a - b、私は必ず持っていa == b + tますか?
3 に答える
絶対違う。明らかなケースの 1 つはa=DBL_MAX、b=-DBL_MAXです。では、またt=INFINITYそうb+tですINFINITY。
さらに驚くべきことは、これがオーバーフローなしで発生する場合があることです。基本的に、それらはすべてa-b不正確な形式です。たとえば、aisDBL_EPSILON/4およびbisの場合-1、a-bis 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 を比較するときは、等値を使用しないでください。代わりに、両方の値の差の絶対値と、必要な精度に対して十分小さいイプシロン値を比較します。
浮動小数点の実装が異なると、同じ操作に対して異なる結果が返される可能性があるため、さらに奇妙になります。