-1

編集: この質問がサイトに重複していたため、ここには多くの不満を持っているメンバーがいます。私の弁護では、最初に答えを検索しようとしましたが、検索キーワードが不十分だった可能性がありますが、この特定のコード例に対する直接的で明確な答えを見つけることができませんでした. ** 2009 年**から、ここからリンクされるものがあることを私はほとんど知りませんでした。

コード例を次に示します。

#include <iostream>
using namespace std;

int main() {
    float x = 0.1 * 7;
    if (x == 0.7)
        cout << "TRUE. \n";
    else
        cout << "FALSE. \n";

    return 0;
}

これは FALSE になります。ただし、x を出力すると、実際には 0.7 として出力されます。説明?

4

4 に答える 4

7

What Every Computer Scientist Should Know About Floating-Point Arithmetic をお読みください。

まず、0.1は type のリテラルですdouble。IEEE 754 倍精度で 0.1 に最も近い表現可能な値は次のとおりです。

0.1000000000000000055511151231257827021181583404541015625

これに 7 を掛けると、IEE 754 単精度で表現可能な最も近い値は次のようになります ( に格納しているためfloat)。

0.699999988079071044921875

ご覧のとおり、これはほぼ0.7 ですが、完全ではありません。これは比較のために a に変換されdouble、次の 2 つの値を比較することになります。

0.699999988079071044921875 == 0.6999999999999999555910790149937383830547332763671875

もちろん、これは に評価されfalseます。

于 2013-04-28T21:33:21.520 に答える
1

これは、数値が 2 進数で格納されているためです。2 進数では、分数 .1 または .7 を有限の桁数で正確に表現することはできません。1/2 のようなものは表現 .1 で正確に表すことができますが、たとえば 10 進数の .1 は .0001100110011 です.... したがって、この数値を切り捨てると、丸め誤差が生じることになります。

于 2013-04-28T21:34:01.733 に答える
0

==double と float は、演算子によって比較されるべきではありません。バイナリでは有限表現 (たとえば 0.1) を持つ必要がないため、数値は不正確にメモリに格納されます。

ここに表示されます:

#include <iostream>
using namespace std;

int main() {
    float x = 0.1 * 7;
    cout << x-0.7;
    return 0;
}

差はゼロではありませんが、ゼロに非常に近いものです。

于 2013-04-28T21:34:00.963 に答える
0

すべてのデータ型と同様に、float は 2 進数として表されます。正確な表現については、http: //en.wikipedia.org/wiki/IEEE_floating_pointを参照してください。

手で 10 進数を浮動小数点数に変換する場合は、まず固定小数点数に変換する必要があります。

0.7 を基数 2 に変換 (バイナリ):

0.7 = 0.101100110011...

ご覧のとおり、コンマの後に無限の桁があるため、float データ型として表すと、一部の桁が切り取られます。これにより、数値を 10 進数に戻すと、正確には 0.7 にはなりません。

あなたの例では、乗算の結果、リテラルの「0.7」とは異なる数値になります。

これを修正するには: float の等価性を比較するときにイプシロンを使用します。

if (x < 0.71f && x > 0.69f)
于 2013-04-28T21:36:26.797 に答える