PHPの数値について考える(2)
PHPの浮動小数点数で気になったことが。
floatの比較について「等しいかどうかを比較するのには問題があります」って。
あぁ、そうなのか。どういう場合だろ。
まず浮動小数点数 (あるいは "float", "double", "実数") の指定から。
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
?>
規約として
LNUM [0-9]+ DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*) EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})
ここで初めて知りましたが、指数が使えたんですね。。。
比較の話に戻ります。
比較については浮動小数点数の精度の話が影響しています。
書いてある内容としては
・少数点数の桁数が多くなると丸め誤差が発生する
・有理数のいくつか(0.1や0.7)は正確に表現できない
少数点の計算は気をつけてね!
って話なのか。これは。
回避方法も書いてあります。
浮動小数点数値が等しいかどうかを調べるには、比較時の丸め誤差の上界を用います。
この値は計算機イプシロンあるいは丸め単位と呼ばれ、 計算時に扱える最小の差分を表します。
言っている事はなんとなくわかりますが、計算時に毎回これは考えてプログラムは組めない。。。
とりあえずサンプルコードを見てみます。
$a と $b は、精度 5 桁では等しくなります。
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
?>
ある指定した桁数以下かどうかをみてるのかな。
丸められててもOKって計算だと推測。
(精度7桁まで等しいけど、5桁?深くかんがえちゃだめだ。)
金融とかだとすごく影響があるらしい。
知っておいても損はないかと。