[PHP]浮動小数点数の比較

プログラミングの常識ではありますが、PHPでも浮動小数点数の比較には注意が必要です。例えば、次のプログラム。

$a = 8;
$b = (0.1 + 0.7) * 10;
if ($a == $b) {
echo '等しい';
} else {
echo '等しくない';
}

「(0.1 + 0.7) * 10 = 8」だから、出力は「等しい」! と思いきや、「等しくない」と出力されてしまいます(実行環境によって誤差があるようですが…)。

これは、(0.1 + 0.7)の結果が、PHPの内部では 0.79999999999999991118…のようになっているからです。ちなみに、$b = 0.8 * 10; とすると、「等しい」と出力されます。浮動小数点数について詳しくは、PHPマニュアル:浮動小数点数を参照して下さい。

では、浮動小数点数の比較をするにはどうすればよいか? これもPHPマニュアルに書いてあるやり方ですが、

$a = 8;
$b = (0.1 + 0.7) * 10;
$epsilon = 0.00001; // 小数点数の丸め誤差上限
if (abs($a - $b) < $epsilon) {
echo '等しい';
} else {
echo '等しくない';
}

という風に、小数点数の丸め誤差上限を定めた上で、2つの値の差分の絶対値をとって誤差を測定すればよいのです。ここでは、小数点以下5桁の精度で比較しています。実験してみたところ、上のプログラムであれば、小数点以下40桁の精度でも「等しい」という結果が出ます。

コメントをどうぞ

コメントを残す