浮動小数点演算には欠陥があるだけでなく、時にはその表現is flawed tooがあるため、ここに該当します。
あなたが実際に0.1、0.2、...得ることはありません - それは確認することは非常に簡単です:
$start = 0;
$stop = 1;
$step = ($stop - $start)/10;
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
唯一の違いはここに、あなたが見るように、echo
はnumber_format
呼び出しに置き換えられていることです。しかし、結果は大きく異なります:
0.10000000000000000555111512312578
0.20000000000000001110223024625157
0.30000000000000004440892098500626
0.40000000000000002220446049250313
0.50000000000000000000000000000000
0.59999999999999997779553950749687
0.69999999999999995559107901499374
0.79999999999999993338661852249061
0.89999999999999991118215802998748
0.99999999999999988897769753748435
を参照してください。実際には一度だけ0.5
でした。その数はフロートコンテナに格納できるためです。他のすべては近似値だけでした。
これを解決するにはどうすればよいですか?まあ、1つの根本的なアプローチは、浮動小数点ではなく、整数を使用して同様の状況です。それは
$start = 0;
$stop = 10;
$step = (int)(($stop - $start)/10);
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
...それはOK働くだろう...あなたはそれをこのように行っていることに気づくのは簡単です:
を別の方法として、あなたには、いくつかの文字列に浮動小数点数を変換するためにnumber_format
を使用することができ、その後、これを比較しますpreformatted floatの文字列です。このように:
$start = 0;
$stop = 1;
$step = ($stop - $start)/10;
$i = $start + $step;
while (number_format($i, 1) !== number_format($stop, 1)) {
print(number_format($i, 32) . "\n");
$i += $step;
}
を驚くほど、あなたは20に間隔を分割する場合:=($停止 - $スタート)$ステップ/ 20;それもOKです – user4035
おそらく丸め浮動小数点エラーです。 – Blazemonger
http://stackoverflow.com/questions/3726721/php-math-precisionに関連する – j08691