-1

重複の可能性:
floatとfloatリテラルを比較した場合の奇妙な出力

このコードがわかりません。2つの同じ数値をどのように比較できますか?

#include<stdio.h>

int main()
{
    float a=0.8;
    if(0.8>a)     //how can we compare same numbers?
        printf("c");
    else
        printf("c++");
    return 0;
}

この問題はどのように解決できますか?

4

2 に答える 2

2

同じ2つの数字を比較できるかどうかを尋ねる理由がわかりません。3 > 33は3と同じですが、なぜこのような比較が機能することを期待しないのでしょうか。>演算子は、左側が右側よりも大きい場合はtrueを返し、そうでない場合はfalseを返します。この場合、.8は、より大きくないaため、結果はfalseになります。

他の人々は、あなたが浮動小数点の丸めの問題について質問していると思っているようです。ただし、正確な数学を使用しても、.8 > .8は誤りであり、それが、示したコードで得られる結果です。elseブランチが取得されます。したがって、ここで説明する予期しない動作はありません。

あなたの本当の質問は何ですか?

浮動小数点効果について質問している場合は、以下にいくつかの情報を示します。

Cソースでは、テキスト「.8」は、.8に最も近い倍精度で表現できる数値の1つを表します。(適切な実装では最も近い数値を使用しますが、C標準では多少の余裕があります。)最も一般的な浮動小数点形式では、.8に最も近い倍精度値は(16進数の浮動小数点数値として)0x1.999999999999ap-です。 1、これは(10進数で)0.8000000000000000444089209850062616169452667236328125です。

この理由は、2進浮動小数点は、2の累乗を表すビットのみで数値を表すためです。(2の累乗は浮動小数点値の指数に依存しますが、指数に関係なく、小数部のすべてのビットは、.5、.25、.125、.0625、および.0625などの2の累乗を表します。 .8は2の累乗の正確な倍数ではないため、小数部の使用可能なビットがすべて使用される場合、結果の値は.8にのみ近くなります。正確ではありません。

初期化float a = .8;により、倍精度値が単精度に変換されるため、に割り当てることができます。単精度では、.8に最も近い表現可能な数値は0x1.99999ap-1(10進数では0.800000011920928955078125)です。

したがって、「。8」をaと比較すると、それ.8 > aは誤りであることがわかります。

.7などの他の値の場合、最も近い表現可能な数値は異なる方法で処理され、関係演算子はtrueを返します。たとえば、.7 > .7ftrueです。(ソースコードのテキスト「.7f」は、.7に近い単精度浮動小数点値を表します。)

于 2012-08-01T12:48:25.010 に答える
1

0.8はダブルです。aを設定すると、フロートに変換され、この時点で精度が低下します。比較はfloatを取得し、それをdoubleに戻すようにプロモートするため、値は確かに異なります。

編集:私は私の主張を証明することができます。プログラムをコンパイルして実行しただけです

float a = 0.8;
int b = a == 0.8 ? 1 : 0;
int c = a < 0.8 ? 1 : 0;
int d = a > 0.8 ? 1 : 0;

printf("b=%d, c=%d, d=%d, a=%.12f 0.8=%.12f \n", b, c, d, a, 0.8);
b=0, c=0, d=1, a=0.800000011921 0.8=0.800000000000

ダブルへの昇格により、現在の派閥部分が非常に小さいことに注目してください

于 2012-08-01T12:14:40.400 に答える