float変数の比較結果

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ポアンカレ

float変数の比較結果

#1

投稿記事 by ポアンカレ » 15年前

 初めて質問させて頂きます.
 以下のようなコードを作成致しましたが,変数xが
0.1であるにもかかわらず,大小関係の判定に誤りが
見られます.コーディングの理解に誤りがありましたら
ご指摘頂ければ大変助かります.

 よろしくお願い致します.

----- ココカラ -----
●ソースコード
#include <stdio.h>
main()
{
float x;
x=0.1;

printf("%d\n", x < 0.1);
printf("%d\n", x == 0.1);
printf("%d\n", x <= 0.1);
}

●実行結果
0
0
0
----- ココマデ -----

Eeel

Re:float変数の比較結果

#2

投稿記事 by Eeel » 15年前

0.1 というのはdouble型です。
printf("%d\n", x < (float)0.1);
printf("%d\n", x == (float)0.1);
printf("%d\n", x <= (float)0.1);
として型を合わせれば正しい判定になります。
なぜdouble型とfloat型で判定が変わるのかについては、
こちらのサイトに詳しい説明がありました。

http://www.cc.kyoto-su.ac.jp/~yamada/pB/float.html

簡単に説明しますと
0.1は二進数では無限少数になります。
(1/3=0.333333・・・が3進数では0.1と表記できるように、数が無限少数であるかどうかは何進数かで変わります)
そして、double型とfloat型ではその無理数を扱う桁が違います。
ですので、0.3333 == 0.33333333 のような式になってしまい、想定通りの判定が行われない事になります。

box

Re:float変数の比較結果

#3

投稿記事 by box » 15年前

float型やdouble型のような浮動小数点数は、
ほとんどの場合誤差を伴います。
「小数」であって「少数」ではありません。

数学的には厳密に0.1であっても、
コンピュータではそうなりません。

試しに、

    printf("%.10f\n", x);

こんなコードを付け加えてみると、お使いの環境では
xが0.1よりごくわずかに大きいことがわかるでしょう。
私のところでは0.1000000015と出力しました。

なお、Eeelさんが書かれたようなキャストを行なったからといって、
xが0.1に等しいという論拠にはなりません。

xの内部表現(メモリ中の0と1のパターン)と、
float型にキャストした0.1の内部表現とが等しいというだけです。
約0.1000000015と約0.1000000015とは確かに等しいです。
しかし、0.1ではありませんね。そういうことです。

ねこ

Re:float変数の比較結果

#4

投稿記事 by ねこ » 15年前

boxさんの言われる通り小数はビット表現では近似値となる値が大半なため誤差が出ます。

こんな風に減算結果の絶対値がある程度の値未満なら同値であるというマクロか関数を用意しておくと良いかもしれません。
#define EQUALSF( A, B ) ( ( fabs( A - B ) < 0.001 ) ? TRUE : FALSE )

閉鎖

“C言語何でも質問掲示板” へ戻る