-1

重複の可能性:floatとfloatリテラルの比較における、
floatとdoubleの比較の奇妙な出力の最も効果的な方法

int main() 
{
  float a = 0.8;
  if (a == 0.8)
    printf("x\n");
  else 
    printf("y\n");

  return 0;
}

a0.8ですが、 y を出力します。

4

8 に答える 8

8

0.8 は、2 進浮動小数点では正確に表すことができません。コードif (a == 0.8)は基本的に、単精度 0.8 と倍精度 0.8 を比較しますが、これらは等しくありません。

これを自分で確認するには、次のコードを試してください。

int main()
{
    double a = 0.8f;
    double b = 0.8;

    printf("%lX\n", *(long *)&a);
    printf("%lX\n", *(long *)&b);
}

以下を出力します。

3FE99999A0000000
3FE999999999999A
于 2012-08-14T16:36:16.540 に答える
6
if (a==0.8f)

代わりにこれを試してください。デフォルトでは、型は double と見なされ、比較すると精度エラーがあります。

于 2012-08-14T16:36:12.703 に答える
3

リテラルの 0.8 を使用していますが、必ずしも浮動小数点数であるとは限りません。使用してみてください:

if (a==0.8F)

代わりは

また、数値の小数部分を表すことは、コンピューターが内部で基数 2 を使用しているため、エラーが発生しやすいことで有名です。

于 2012-08-14T16:36:02.100 に答える
1

浮動小数点数は正確な値ではありません。== と != を使用してそれらを比較することは想定されていません。大なり演算子と小なり演算子を適度に小さいイプシロンで使用します。

if ((a > 0.79) && (a < 0.81))
于 2012-08-14T16:37:17.537 に答える
0

フロートは常に100%正確であるとは限りません。保存方法が原因で、フロートが正確であるとは限りません。あなたが言うならfloat a = 0.8、aは本当にそうかもしれない0.800000000001かそのようなものかもしれません。これを補うために、ある種のしきい値を使用する必要があります。if (fabs(a-0.8) < 1.0e-5)代わりに試してください

于 2012-08-14T16:38:07.693 に答える
0

浮動小数点数の場合、0.8は実際には0.8を意味しませんが、0.799999999であるため、発生 します。なぜ
0.79999999であるか これは、浮動小数点値の格納に依存します。10進値は、バイナリ形式(....、2 ^ 3,2 ^ 2,2 ^ 1,2 ^ 0、。、2 ^ -1,2 ^ -2,2 ^ -3、。。 。)

したがって、0.8が2の倍数で.101b(0.8ではなく0.799999988)として格納される場合、その値は0.8未満になります。

if (a > 0.8) 

それもFalse理由です。

あなたの結果のために試してみてください

if (a == 0.8f) 
于 2012-08-14T16:38:36.403 に答える
0

これは、浮動小数点が 10 進数を正確に表すことができないため、正確に 0.8 ではないためです。そして、浮動小数点数として丸められた 0.8 と小数として丸められた 0.8 を比較していますが、必ずしも同じではありません。

于 2012-08-14T16:36:11.010 に答える
0

異なるタイプの 2 つの値を比較しています: ais of type float0.8is of type double

比較の前に、float値はdouble... に変換されますが、からの変換doublefloatその逆の変換では、必ずしも同じ値が得られるとは限りません

if (0.8 == (double)(float)0.8) /* ... */
于 2012-08-14T16:59:40.557 に答える