PHPで浮動小数点数を比較するにはどうすればよいですか?

怪我咯
リリース: 2023-03-13 14:42:01
オリジナル
4097 人が閲覧しました

浮動小数点数は変換処理中に誤差が生じるため、通常、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=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の2進法は0.1

8.52進法は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.8x2=1.6

… その後、ループが続きます。イオン精度が N の場合、N 以降の数値は四捨五入されるため、精度が失われます。

上記の例では、バイナリに変換すると 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
?>
ログイン後にコピー

2. 高精度の算術メソッドを使用します

最初に操作を実行します。高精度の計算方法を使用する場合、これにより精度が失われることがなくなります。

高精度演算の方法は以下の通りです:

bcadd

2つの高精度数値を加算

bccomp

2つの高精度数値を比較し、-1,0を返す、 1

bcp

2つの高精度数値を除算します

bcmod

高精度数値の余りを求めます

bcmul

2つの高精度数値を掛けます

bcpow

高精度の数値べき乗

bcpowmod

高精度の数値べき乗と法を求めます

bcscale

Linux bc

の「scale=」に相当するデフォルトの小数点数を設定しますbcsqrt

高精度数値の平方根をリクエスト

bcsub

2つの高精度数値を減算例:

<?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 サイトの他の関連記事を参照してください。

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