akkun_choi pedia
mindiaakkun_choi pedia見出し語

float

akkun_choi · 2009-06-17 更新

不思議。

>|php|
<?php
$a = 0.4 + 2 / 10;
$b = 0.6;

var_dump($a);
var_dump($b);
var_dump($a == $b);
var_dump($a === $b);

||<

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.float.php

1/3とかはダメな感じがするけど、2/10でもダメなんだな。
まてよ、他の言語ではどうだろう。

Java

>|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

>|ruby|
a = 0.4 + 2.0 / 10.0;
b = 0.6

p a;
p b;
p a == b;
||<

0.6
0.6
false

関連する見出し語