2011-07-30 14 views
4

可能性の重複:!上記のコードで
problems in floating point comparison浮動小数点比較 `= 0.7`

#include <stdio.h> 
#include <conio.h> 

main() 
{ 
    float a = 0.7; 
    if(a < 0.7) 
     printf("C"); 
    else 
     printf("C++"); 
} 

、出力がCです。私はこのコードをCode :: BlocksとPelles Cで試しましたが、同じ答えがありました。私はこれの理由を詳細に知りたいです!

+6

[浮動小数点ガイド](http://floating-point-gui.de/)と[浮動小数点演算についてすべてのコンピュータ科学者が知っておくべきこと](http://download.oracle.com/)をご覧ください。 com/docs/cd/E19957-01/806-3568/ncg_goldberg.html) – Bart

答えて

19

、0.7である。

b0.1011001100110011001100110011001100110011001100110011001100110... 

しかし、0.7はその値0.7であり、最も近い表現可能な倍精度値に丸められ、倍精度リテラルである:

b0.10110011001100110011001100110011001100110011001100110 
小数で

は、それが正確だ:

0.6999999999999999555910790149937383830547332763671875 

あなたはを書くとき

b0.101100110011001100110011 

小数で正確

0.699999988079071044921875 

ある:double値を単精度に再び丸められること、およびaバイナリ値を取得します。

(a < 0.7)を実行すると、この単精度値(すべての単精度値が倍精度で表現できるため丸められないdouble型に変換されます)が元の倍精度値と比較されます。したがって、比較は正しくtrueを返し、プログラムは"C"を出力します。

これは、C++では異なるものではなく、逆の問題のコードの外観です。ビヘイビアを変更できる特定の(数値的に安全でない)コンパイラの最適化がありますが、CやC++に固有のものではありません。

+0

良いdemontstration、+1 – unkulunkulu

+0

ok ...ありがとうございます!それは多くの助けになった! –

8

0.7はタイプdoubleであるため、adoubleに変換され、このタイプで比較されます。 0.7は正確に2進浮動小数点で表現できないため、丸め誤差が発生し、比較が真となります。

次のことが可能です。

if(a < 0.7f) { 
.... 

しかし、実際には、この効果はC++すぎのために真であるので、あなたの条件が正確に正当ではありません。

+0

Ok ..thanx a lot !! –

3

バートは彼のコメントに非常に良いの参照を与えたが、私もこの非常に単純なルールをお勧めします:

をすべての数値は、(そうとすぐに浮動小数点数を使用して、コンピュータで正確に表現できるわけではありません浮動小数点数型と倍精度型の両方)、それぞれの格納された数値には、予測できない小さな誤差が存在することが予想されます。いいえ、実際にはランダムでも予測できないわけでもありませんが、それについてもっと知るまで、予測不可能と考えることができます。したがって、あなたの< 0.7のような比較は真実である可能性があります。それに依存するコードを書き込まないでください。

バイナリ
+0

このような比較は一度も使用していませんが、浮動小数点値を比較する必要がある場合はどうすればよいですか? –

関連する問題