PHPの浮動小数点数比較方法の説明

jacklove
リリース: 2023-03-31 07:38:01
オリジナル
1490 人が閲覧しました

浮動小数点数演算の精度の問題

最初に例を見てみましょう:

<?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.00000000000000000000printf("%.20f", $c-$b); // 0.09999999999999997780?>
ログイン後にコピー

$c-$b は 0.09999999999999997780 であるため、0.1 と比較すると が返されます。 false

この問題は、浮動小数点数の計算には精度が含まれるため、浮動小数点数を 2 進数に変換すると精度が失われる可能性があるために発生します。

浮動小数点数の変換方法

整数部分を で割って余りを 2 でとります方法
小数部分はを乗算します。 四捨五入方法

例: 数値 8.5 を 2 進数に変換します
整数部分は 8
8/ 2=4 8%2 =0
4/2=2 4%2=0
2/2=1 2%2=0
1 は 2 より小さいため、計算する必要はありません。整数 8 の 2 進法は 1000

小数部分は 0.5
0.5x2 = 1.0
小数部分は 0 なので、四捨五入後はもう計算する必要はありません。
10 進数 0.5 0.1

8.5 の 2 進表現は 1000.1

です。数値のバイナリ表現を計算します 0.9
0.9x2= 1.8
0.8x2=1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8 x2=1.6
… 以降、ループが続きます。迎撃精度がNの場合、N以降の数値は四捨五入されるため、精度が失われます。
上記の例では、バイナリに変換すると 0.9 の精度が失われ、比較中にエラーが発生します。

したがって、浮動小数点数が最後の桁まで正確であるとは決して信じないでください。また、2 つの浮動小数点数が等しいかどうかを比較してはいけません。

浮動小数点数を正しく比較する方法

1. ラウンド方式を使用して処理し、比較します
例:

<?php$a = 0.1;$b = 0.9;$c = 1;
var_dump(($c-$b)==$a);                   // falsevar_dump(round(($c-$b),1)==round($a,1)); // true?>
ログイン後にコピー


2. 高精度の計算方法を使用する
最初に計算を実行するときは、精度が失われないように高精度の計算方法を使用してください。

高精度演算の方法は次のとおりです。
bcadd 2 つの高精度数値を加算します。
bccomp 比較します。 2 つの高精度数値、-1,0,1 を返します
bcp 2 つの高精度数値を除算します
bcmod 高精度数値の余りを求めます
bcmul 2 つの高精度数値の乗算
bcpow 高精度数値の累乗を求めます
bcpowmod の累乗の係数を求めます高精度数値
bcscale Linux bcの「scale=」に相当するデフォルトの小数点数を設定します。
bcsqrt 高精度数値の平方根を求めます。 number
bcsub 2 つの高精度数値減算を結合する

例:

<?php$a = 0.1;$b = 0.9;$c = 1;
var_dump(($c-$b)==$a);          // falsevar_dump(bcsub($c, $b, 1)==$a); // true?>
ログイン後にコピー

この記事では、PHP の浮動小数点数の比較方法について説明します。その他の関連コンテンツについては、こちらをご覧ください。 PHP 中国語 Web サイトに注意してください。

関連する推奨事項:

mysql を介してクエリ結果を CSV にエクスポートする方法の説明

#php array_push と $arr[ ] =$value パフォーマンスの比較

php を使用して有効期限を厳密に制御するセッションをセットアップする方法

以上がPHPの浮動小数点数比較方法の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート