浮動小数点比較パズル
次の C コードを考えてみましょう。
int main() { float a = 0.7; float b = 0.5; if (a < 0.7) { if (b < 0.5) printf("2 are right"); else printf("1 is right"); } else printf("0 are right"); }
直感的には次のような出力が期待されるでしょう。 「0 が正しい」になります。しかし、驚くべき結果は「1が正しい」。なぜこのようなことが起こるのでしょうか?
浮動小数点比較の落とし穴
鍵は、C における浮動小数点数と倍精度数値の違いにあります。コードでは、変数 a と b は 32 ビット浮動小数点数である float として宣言されます。ただし、リテラル 0.7 と 0.5 は double として扱われるため、両方の比較 (a
比較中に、float 変数は double に昇格され、より高い範囲と精度。ただし、この変換では、float の精度が限られているため、微妙なアーティファクトが発生する可能性があります。この場合、float としての 0.7 は double としての 0.7 とまったく同じではありません。
具体的には、float としての 0.7 は、IEEE 754 標準では 0x3f000000 として表されます。 double に昇格すると、この値は 0.7 を正確に表しません。代わりに、0x3f00000000000000 (約 0.7000000000000001) 程度に大きくなります。
予期しない結果の原因
このプロモーションの結果、条件 a < a の double 表現が 0.7 よりわずかに小さいため、0.7 は true になります。続いて、2回目の比較b<>となる。 b (正確に double として表される) は 0.5 に等しいため、0.5 は false と評価されます。したがって、コードは「1 が正しい」と出力します。
解決策
この問題を解決するには、次のいずれかを行うことができます。
以上がC で float と double リテラルを比較すると、予期しない結果が生じるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。