なぜ浮動小数点値条件が 'if'条件で失敗したのですか?

可能重複:
  浮動小数点数と浮動小数点数を比較して異常な出力

ここにコードがあります

#include
int main()
{
 float a=0.3;
 if(a==0.3)
  printf("Hello World!");
 else
  printf("Stack Overflow");
 return 0;
}

私は "Hello World"としての出力を期待していました。しかし、私は "スタックオーバーフロー"を得た。なぜ私は "Hello World"を取得しませんでしたか?

if条件に何か問題はありますか?

0
この場合、 0.3 は二重リテラルなので、 a double に昇格されます。 0.3 は正確に表現できないので、比較は失敗します。
追加された 著者 David Heffernan,
C ではありませんが、浮動小数点数にする必要があります。 a == 0.3f ;
追加された 著者 Ash Burlaczenko,
前者は float に切り捨てられているため、(double)(float)(0.3) 0.3 後者は double の精度を保持します。基数10の類推のために、私が 1/3 をとり、それを3桁の有効数字: 0.333 にすると仮定します。それは "float" a です。ここで a の値を6桁の有効数字( "double")の値に変換します: 0.333000 。これは 0.333333 (1/3の値は "double")と等しくありません。
追加された 著者 Steve Jessop,

6 答え

浮動小数点数の比較

浮動小数点数は正確ではありません。 0.2のような単純な値は、2進浮動小数点数を使用して正確に表現することはできません。浮動小数点数の精度が限定されているため、操作のわずかな変更によって結果が変更される可能性があります。異なるコンパイラとCPUアーキテクチャでは、異なる精度で一時的な結果が格納されるため、環境の詳細によって結果が異なります。あなたが計算を行い、結果をある期待値と比較すると、あなたが意図した結果を得ることはほとんどあり得ません。

次のようにしてください:

#include
int main()
{
 float a=0.3;
 float acceptedDiff = 0.0000001;
 if(fabsf(a-0.3) < acceptedDiff)
  printf("Hello World!");
 else
  printf("Stack Overflow");
 return 0;
}
5
追加された
ありがとうMichałPowaga :)
追加された 著者 Dinesh,
正確で安全な方法は、差異ではなく2つの数字の相対的な差異を常に見ることです。
追加された 著者 Jimmy Pettersson,

それを試してください:)

if (a == 0.3f)

または

if (a == (float)0.3)
2
追加された

浮動小数点値は、 == または!= 演算子のいずれかを使用して比較してはなりません。 ほとんどの浮動小数点値は正確なバイナリ表現を持たず、精度が限られています。 あなたができることを見てください

0
追加された

0.3のような値は、2進浮動小数点数を使って正確に表現できないからです。一時的な値は別々に格納されるため、これと比較することはできません。 したがって、aと0.3の値は異なる方法で格納され、このような直接比較には依存することはできません。

0
追加された

はい、私が知っている限り、IFステートメントは変数と値をマシンレベルの情報と値の格納に入れて比較します。

非常に最初の行は浮動小数点型としてa = 0.3と宣言しています。したがって、ビットの余分なパディングとともにメモリにバイナリ形式で格納されます。厳密な「0.3」と比較すると常に失敗します。

0
追加された