浮動小数点数は変換処理中に誤差が生じるため、通常、2 つの浮動小数点数を比較する場合、その差が 2 つの数値以内であれば比較されます。が許容範囲内にある場合、2 つの浮動小数点数は等しいと見なされます。この記事では参考値の高いphp浮動小数点数の比較方法を中心に紹介します。以下のエディタで見てみましょう
浮動小数点数演算の精度の問題
まず例を見てみましょう:
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($a+$b)==$c); var_dump(($c-$b)==$a); ?>
$a+$b==$cはtrueを返します、正しい
$c- $b==$a false、エラーを返します
なぜこのようなことが起こっているのでしょうか?
精度20桁の場合の演算後、実際に返される内容は以下の通りです:
<?php $a = 0.1; $b = 0.9; $c = 1; printf("%.20f", $a+$b); // 1.00000000000000000000 printf("%.20f", $c-$b); // 0.09999999999999997780 ?>
$c-$bは0.09999999999999997780なので、0.1と比較するとfalseを返します
この問題は浮動小数点演算であるために発生します浮動小数点数を 2 進数に変換すると、精度が失われる可能性があります。
浮動小数点数から2進数への変換方法
整数部分はを2で割って余りを取る方法
小数部分はを2倍して切り上げる方法
例: 数値を変換 8.5 バイナリに変換
整数部分は 8
8/2=4 8%2=04/2=2 4%2=0
2/2 =1 2%2=0
1000
小数部分は 0.5
0.5x2 です。 = 1.0四捨五入後の小数部は0なのでこれ以上計算する必要はありません10進数0.5の2進法は0.18.52進法は1000.1
バイナリシステム数値の 0.9
0.9x2=1.80.8x2 =1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8x2=1.6
上記の例では、バイナリに変換すると 0.9 の精度が失われ、比較中にエラーが発生します。
したがって、浮動小数点数が最後の桁まで正確であるとは絶対に信じないでください。また、2 つの浮動小数点数が等しいかどうかを比較しないでください。浮動小数点数を正しく比較する方法
1. ラウンドメソッドを使用して処理し、比較します
例:
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(round(($c-$b),1)==round($a,1)); // true ?>
最初に操作を実行します。高精度の計算方法を使用する場合、これにより精度が失われることがなくなります。
高精度演算の方法は以下の通りです:bcadd
2つの高精度数値を加算
bccomp2つの高精度数値を比較し、-1,0を返す、 1
bcp2つの高精度数値を除算します
bcmod高精度数値の余りを求めます
bcmul2つの高精度数値を掛けます
bcpow高精度の数値べき乗
bcpowmod高精度の数値べき乗と法を求めます
bcscaleの「scale=」に相当するデフォルトの小数点数を設定しますbcsqrt高精度数値の平方根をリクエスト
bcsub2つの高精度数値を減算例:
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(bcsub($c, $b, 1)==$a); // true ?>
以上がPHPで浮動小数点数を比較するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。