不思議。
float(0.6)
float(0.6)
bool(false)
bool(false)
0.1 や 0.7 のようなシンプルな小数であっても、 それを内部的な二進数表現に変換する際には、どうしても多少精度が落ちてしまいます。 その結果、不思議な結果を引き起こすことがあります。たとえば、 floor((0.1+0.7)*10) の結果はたいてい 7 となるでしょう。おそらくは 8 を想定していらっしゃるでしょうが、そのようにはなりません。 これは、(この計算結果の) 内部的な値が 7.9999999999... のようになっているからです。
こうなる理由のひとつとして、「有限小数に変換できない分数がある」 という事実があります。たとえば 1/3 を小数で表そうとすると 0.3333333. . . となります。
よって、小数の最後の桁を信用してはいけませんし、 小数が等しいという比較を行ってはいけません。より高い精度が必要な場合には、 任意精度数学関数または gmp 関数を代わりに使用してください。
http://jp.php.net/manual/ja/language.types...
1/3とかはダメな感じがするけど、2/10でもダメなんだな。
まてよ、他の言語ではどうだろう。
Java
class CompareFloat{
public static void main(String[] args){
double a = 0.4 + 2d / 10d;
double b = 0.6;
System.out.println(a);
System.out.println(b);
System.out.println(a == b);
}
}
0.6000000000000001
0.6
false
あ、javaでもだめなのか。じゃこれはプログラミング界の常識なのかな?
ってかなんか3年に1度ぐらい同じこと調べてる気がするw
Ruby
a = 0.4 + 2.0 / 10.0;
b = 0.6
p a;
p b;
p a == b;
0.6
0.6
false