ホームページ >バックエンド開発 >C++ >C で float と double リテラルを比較すると、予期しない結果が生じるのはなぜですか?

C で float と double リテラルを比較すると、予期しない結果が生じるのはなぜですか?

DDD
DDDオリジナル
2024-12-15 18:48:15504ブラウズ

Why does comparing floats to double literals in C produce unexpected results?

浮動小数点比較パズル

次の 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 が正しい」と出力します。

解決策

この問題を解決するには、次のいずれかを行うことができます。

  • 変数 a と b を double として宣言するか、
  • リテラルを 0.7 と変更しますfloat
として指定される 0.5

以上がC で float と double リテラルを比較すると、予期しない結果が生じるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。