ホームページ >バックエンド開発 >PHPの問題 >PHP での浮動小数点演算は正確ですか?

PHP での浮動小数点演算は正確ですか?

青灯夜游
青灯夜游オリジナル
2023-01-04 20:50:243596ブラウズ

いいえ、PHP での浮動小数点演算ではエラーが発生します。 PHP では、浮動小数点数の精度には限界があります。システムにもよりますが、PHP は一般に IEEE 754 倍精度形式を使用し、丸めによる最大相対誤差は「1.11e-16」です。非基本的な数学演算では A が大きくなる場合があります。エラーが発生するため、複合操作を実行するときのエラーの伝播を考慮する必要があります。

PHP での浮動小数点演算は正確ですか?

このチュートリアルの動作環境: Windows7 システム、PHP8 バージョン、DELL G3 コンピューター

「ポット」浮動小数点数演算の結果 ''

//加
$a = 0.1;
$b = 0.7;
$c = intval(($a + $b) * 10);
echo $c."<br>";
//输出:7

//减
$a = 100;
$b = 99.98;
$c = $a - $b;
echo $c."<br>";
//输出:0.019999999999996

//乘
$a = 0.58;
$b = 100;
$c = intval($a * $b);
echo $c."<br>";
//输出:57

//除
$a = 0.7;
$b = 0.1;
$c = intval($a / $b);
echo $c."<br>";
//输出:6

上記の結果は明らかに私たちが望んでいたものではありません。

PHP 公式マニュアルでは、次のように説明されています:

浮動小数点数には精度が制限されています。システムにもよりますが、PHP は通常 IEEE 754 double 形式を使用するため、丸めによる最大相対誤差は 1.11e-16 です。非基本的な数学演算ではより大きな誤差が生じる可能性があるため、複合演算を実行する場合は誤差の伝播を考慮する必要があります。浮動小数点の結果を最後の桁まで決して信頼しないでください。また、2 つの浮動小数点数が等しいかどうかを比較しないでください。本当に高い精度が必要な場合は、任意精度数学関数 または gmp 関数を使用する必要があります。

ここで重要なのは、浮動小数点数の小数点が 2 進数で表現されていることです。処理は次のとおりです。最初の桁を表す部分;

    小数部に 2 を掛け、整数部分を取り出して 2 番目の桁を表します;
  • 小数部分を 2 で掛け、整数部分を取り出して 2 番目の桁を表します3 桁目;
  • .. など、小数部分が 0 になるまで続きます;
  • 例: 0.58

0.58 * 2 = 1.16 - --> 1

    0.16 * 2 = 0.32 ---> 0
  • 0.32 * 2 = 0.64 ---> 0
  • 0.64 * 2 = 1.28 ---> 1
  • 0.28 * 2 = 0.56 ---> 0
  • 0.56 * 2 = 1.12 ---> 1
  • 0.12 * 2 = 0.24 ---> 0
  • 0.24 * 2 = 0.48 ---> 0
  • 0.48 * 2 = 0.96 ---> 0
  • 0.96 * 2 = 1.92 ---> 1
  • ...
  • 2 進数の 10 進数の無限ループが発生します:
0.1001010001...

小数部分にループがあり、制限された 2 進数では小数を正確に表すことができません。これが、10 進演算でエラーが発生する原因です。

次に、

任意精度の数学関数

を紹介します。

任意精度の数学関数

任意精度の数学の場合、PHP は文字列で表される任意のサイズと精度の数値をサポートするバイナリ計算を提供します。

BCMath: BC は Binary Calculator の略です。

公式マニュアル:

http://php.net/manual/zh/book.bc.php

使用する前に、bcmath がインストールされているかどうかを確認してください。

//加
$a = 0.1;
$b = 0.7;
$c = intval(bcadd($a, $b, 1) * 10);
echo $c."<br>";
//输出:8

//减
$a = 100;
$b = 99.98;
$c = bcsub($a, $b, 2);
echo $c."<br>";
//输出:0.02

//乘
$a = 0.58;
$b = 100;
$c = intval(bcmul($a, $b));
echo $c."<br>";
//输出:58

//除
$a = 0.7;
$b = 0.1;
$c = intval(bcdiv($a, $b));
echo $c."<br>";
//输出:7
加算、減算、乗算、除算に加えて、bcmath は次のメソッドも提供します。

bccomp 2 つの任意精度の数値を比較します。

    bcmod Modulo an任意精度数値
  • bcpow 任意精度数値のべき乗
  • bcpowmod 高精度数値のべき乗の法
  • bcscale すべての小数点保持桁数のデフォルトを設定します。 bc 数学関数
  • bcsqrt任意精度数値の二次根
  • 一般的な数値処理ソリューション

丸め方法 (切り捨て) )

echo floor(5.1);
//输出:5

echo floor(8.8);
//输出:8
四捨五入方法(四捨五入)

echo ceil(5.1);
//输出:6

echo ceil(8.8);
//输出:9
通常の四捨五入方法

echo round(5.1);
//输出:5

echo round(8.8);
//输出:9

//保留两位小数并且进行四舍五入
echo round(5.123, 2);
//输出:5.12

echo round(8.888, 2);
//输出:8.89

//保留两位小数并且不进行四舍五入
echo substr(round(5.12345, 3), 0, -1);
//输出:5.12

echo substr(round(8.88888, 3), 0, -1);
//输出:8.88
銀行ファミリの丸め方法

5 に丸めることを検討します。最後の 5 が空でない場合は、1 を追加します。最後の 5 が空の場合は、奇数または偶数を調べます。最初の 5 が偶数の場合は、最初の 5 つが奇数の場合は、1 つ追加します。

小数点以下 2 桁を保持します (例:

1.2849 = 1.28 ->丸め

    1.2866 = 1.29 ->6 エントリ
  • 1.2851 = 1.29 -> 最後の 5 つが空でない場合は、1 を追加します
  • 1.2850 = 1.28 -> 最後の 5 つが空の場合は、奇数または偶数を調べ、最初の 5 つが偶数かどうかを確認します、破棄してください
  • 1.2750 = 1.28 -> ; 最後の 5 つが空の場合は、奇数と偶数を調べ、最初の 5 つが奇数の場合は、
  • の 1 つに進みます。 #実装コードは次のとおりです:
  • echo round(1.2849, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
    
    echo round(1.2866, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.29
    
    echo round(1.2851, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.29
    
    echo round(1.2850, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
    
    echo round(1.2750, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
  • ラウンドの使用方法の詳細については、公式マニュアルを確認してください:
http://php.net/manual/zh/function.round.php

数値書式設定 (千の位のグループ化)

銀行カードの残高など、よく見る金額の表示に適用します。
echo number_format('10000.98', 2, '.', ',');
//输出:10,000.98

echo number_format('340888999', 2, '.', ',');
//输出:340,888,999.00

拡張機能

MySQL 浮動小数点フィールド

MySQL では、テーブル フィールドを作成するときに浮動小数点型もあります。 。 浮動小数点数型には、単精度浮動小数点数 (float) と倍精度浮動小数点数 (double) があります。

同様に、浮動小数点数型の使用は推奨されません。 ! !

浮動小数点数にはエラーがあります。精度が重要なデータを使用する場合は、保存に固定小数点数 (10 進数) を使用する必要があります。

まとめ

浮動小数点数の精度の問題を通じて、浮動小数点数の小数が 2 進数で表現されることを学びました。

は、高精度の演算を実行するための PHP 任意精度数学関数 の使用を共有しました。

同時に、四捨五入、四捨五入、銀行四捨五入、数値書式設定などの一般的な数値処理ソリューションも共有されます。

最後に、MySQL の float から PHP の float について考えてみましょう。

今後、浮動小数点計算を使用する場合は、詳細が成功または失敗を決定するため、注意が必要です。

推奨学習: 「PHP ビデオ チュートリアル

以上がPHP での浮動小数点演算は正確ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。