精度の危険:PHPの浮動小数点数を処理します
0.1 0.2!== 0.3バイナリフローティングポイント精度の制限によりPHPで0.3であるため、開発者は直接的な比較を回避し、Epsilonベースのチェックを使用し、BCMATHまたはGMPを使用して、可能な場合は整数に通貨を保存し、慎重にフォーマットし、財務計算のために浮遊精度に依存することはありません。
PHPの数字、特に財務または科学的計算で作業する場合、開発者はしばしば、浮動ポイントの精度によって引き起こされる微妙で深刻な問題に遭遇します。 PHPは整数と文字列を予測可能に処理しますが、フローティングポイント算術は0.1 0.2 !== 0.3
など、一見間違っているように見える結果を生成できます。これはPHPのバグではありません。これは、コンピューターがバイナリの小数数をどのように表すかの結果です。

PHPの浮動小数点精度の危険と、それらを適切に処理する方法を分解しましょう。
なぜフローティングポイント数学がうまくいかないのか
PHPの浮動小数点数(ほとんどのプログラミング言語と同様)は、バイナリ表現のIEEE 754標準に従います。多くの小数分画をバイナリで正確に表すことができないため、問題は発生します。

例えば:
var_dump(0.1 0.2); // float(0.30000000000000004) var_dump(0.1 0.2 == 0.3); // bool(false)
これは1/3
が0.333...
であるように、 0.1
と0.2
バイナリで分数を繰り返しているために発生します。有限メモリ(ダブルのために64ビット)に保存すると、それらは丸くなり、小さな不正確さにつながります。

これらの丸めエラーは蓄積し、原因となる可能性があります。
- 誤った比較
- 計算での予期しない結果
- 金融アプリケーションのバグ(たとえば、誤った合計)
直接平等比較を使用しないでください
最も一般的な間違いの1つは、フローティングポイント数を==
または===
と比較することです。
//❌危険 if(0.1 0.2 == 0.3){ echo "Equal"; //これは実行されません }
代わりに、許容範囲(Epsilon)を使用して、2つのフロートが「十分に近い」かどうかを確認します。
//✅安全な比較 function float sakeal($ a、$ b、$ epsilon = 0.00001){ abs($ a -$ b)<$ epsilon; } if(float sakeal(0.1 0.2、0.3)){ エコー「効果的に等しい」; //これは実行されます }
アプリケーションの必要な精度に基づいて、 $epsilon
を選択します。お金の場合、 0.0001
で十分です。
正確な算術のためにBCMATHまたはGMPを使用します
財務計算のように精度が重要である場合、浮動小数点数を完全に回避します。 PHPは、任意の精度算術のためにBCMATHおよびGMP拡張機能を提供します。
BCMATH:任意の精密小数数学
BCMATHは、文字列として数字を使用し、追加、減算、乗算、分割などを正確にサポートします。
//例:0.1 0.2 = 0.3、正確に $ result = bcadd( '0.1'、 '0.2'、1); // '0.3'
注:すべてのオペランドは文字列でなければならず、スケール(小数点の数)を指定します。
その他の例:
Echo Bcmul( '0.1'、 '0.2'、2); // '0.02' Echo Bcdiv( '1.0'、 '3.0'、5); // '0.33333'
bcmathは次のとおりです。
- 通貨計算
- 税、利息、または請求書の合計
- 丸めエラーが受け入れられない状況
GMP:整数ベースの高精度数学
GMPは大型整数の方が効率的ですが、値をスケーリングできる場合に最適に機能します(たとえば、ドルの代わりにセントを保存します)。
$ amoled1 = gmp_init(10); // 10セント $ humbory2 = gmp_init(20); // 20セント $ Total = GMP_ADD($額1、$ 2); // 30セント Echo GMP_STRVAL($合計); // "30"
これは、支払いシステムの一般的な小数を完全に回避します。
問題のフォーマットと表示の問題
内部計算が正しい場合でも、フロートを表示すると誤解を招く可能性があります。
エコー0.29 * 100; // 28.9999999999996を表示する場合があります
number_format()
またはprintf()
を使用して出力を制御します。
echo number_format(0.29 * 100、2); // "29.00"
ただし、覚えておいてください。フォーマットは、根本的な価値ではなく、ディスプレイにのみ影響します。
ベストプラクティスの概要
PHPの浮動小数点の落とし穴を避けるため:
- floatを直接比較しないでください- イプシロンを使用します。
- bcmathを財務または高精度の小数数学に使用します。
- 可能な場合は、通貨をセント(整数)に保存します。
- sinted意図的に入力値を検証および丸めます。
- typeジャグリングに慎重になります-PHPは静かにストリングをフロートに変換する可能性があります。
安全なお金の取り扱いの例:
// BCMATHを使用してセントに2つの量を追加します 関数addMoney($ a、$ b){ return bcadd($ a、$ b、0); //セントの小数点はありません } $ TotalCents = addMoney( '150'、 '250'); // '400'セント= $ 4.00
浮動小数点数は、科学的または近似計算に役立ちますが、正確な算術に適していない。 PHPでは、キーは、デフォルトのフロート動作の外側を踏み出し、BCMATHなどのツールを使用して精度を維持するタイミングを知ることです。
基本的に:精度が重要な場合は、小数点を信頼しないでください。
以上が精度の危険:PHPの浮動小数点数を処理しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undress AI Tool
脱衣画像を無料で

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

PHPは、ゆるいタイプと厳格なタイプの共存をサポートします。これは、スクリプト言語から最新のプログラミング言語への進化の中心的な特徴です。 1.ゆるいタイプは、迅速なプロトタイピング、動的なユーザー入力の処理、または外部APIでのドッキングに適していますが、暗黙のタイプ変換のリスク、デバッグの難しさ、ツールサポートの弱いなどの問題があります。 2。decrare(strict_types = 1)で厳密なタイプが有効になります。これは、事前にエラーを検出し、コードの読みやすさとIDEサポートを改善することができ、コアビジネスロジック、チームコラボレーション、データの整合性の高い要件を備えたシナリオに適しています。 3。実際の開発で混合使用を使用する必要があります。デフォルトでは厳密なタイプが有効になり、緩いタイプは入力境界で必要な場合にのみ使用され、検証とタイプ変換はできるだけ早く実行されます。 4.推奨されるプラクティスには、PHPSTAの使用が含まれます

upgradephp7.xcodebasestophp8 byreplacingphpdoc-suggestedtypeslike@paramstring | intwithnativeuniontypessuchasstring | intforparametersandreturntypes、whithemprovestypeSafetyandclarity;

0.1 0.2!== 0.3inphpduetobinary floating-precisionlimitations、sodevelopersmustavoiddirectcomparisonsandusepsilonベースのチェック、empluebcmathorgmtic、emplovebcmathorgmetic、storecurrencyinintegersegorsible、formatutcoputputputputputtutputpotised、およびneverrelelelyonfrocisis

returntypesinphpimprovecoderiability andclaritybysifyifiecifyive whatafunctionmusterturn.2.usebasictypeslikestring、array、ordatetimetoenforcorcreturnvaluesandcatcherrorsearly.3.ApplynullabletypeSwith?(E.G。、?

acallable inphpisapsapsodo-typereprepreSentingnayvaluethatcanbeedusings the()演算子は、主に使用されています

php8.1で導入された酵素は、魔法の価値の問題を解決するタイプセーフ定数コレクションを提供します。 1. enumを使用して、ステータス::ドラフトなどの固定定数を定義して、定義された値のみが利用可能であることを確認します。 2。列挙型をバックデナムに介して弦または整数にバインドし、スカラーと酵素間の()とtryfrom()からの変換をサポートします。 3。酵素は、ビジネスロジックのカプセル化を強化するために、color()やisedable()などの方法と動作を定義できます。 4。動的データではなく、状態や構成などの静的シナリオに適用できます。 5.タイプの制約のためにUnitenumまたはBackedenumインターフェイスを実装し、コードの堅牢性とIDEサポートを改善し、

PHPはZVAL構造を使用して変数を管理します。答えは次のとおりです。1。ZValには、16バイトのサイズの値、タイプ、メタデータが含まれています。 2。タイプが変更されたら、組合とタイプ情報のみを更新する必要があります。 3。複雑なタイプは、ポインターを介した参照カウントを持つ構造を指します。 4.値を割り当てるとき、コピーを使用してメモリを最適化します。 5。参照変数が同じZVALを共有するようにします。 6.リサイクル参照は、特別なゴミコレクターによって処理されます。これは、PHP変数の動作の根本的なメカニズムを説明しています。

PHPのメモリ管理は、参照カウントとサイクルリサイクルに基づいています。さまざまなデータ型がパフォーマンスとメモリの消費に大きな影響を与えます。1。整数と浮動小数点数は、メモリの使用量が少なく、最速の操作があり、最初に数値操作に使用する必要があります。 2。文字列は、書き込みオンワイトのコピーメカニズムを採用していますが、大きな文字列または頻繁なスプライシングはパフォーマンスの問題を引き起こすため、最適化を破裂することをお勧めします。 3.アレイメモリオーバーヘッドは大きく、特に大きいまたはネストされた配列です。ジェネレーターは、大規模なデータセットを処理し、タイムリーに変数をリリースするために使用する必要があります。 4.オブジェクトは参照モードで渡され、インスタンス化と属性アクセスは遅いです。これは、行動のカプセル化が必要なシナリオに適しています。 5。リソースタイプは手動でリリースする必要があります。そうしないと、システムレベルの漏れにつながる可能性があります。パフォーマンスを改善するには、データ型を合理的に選択し、メモリを時間内にリリースし、グローバル変数によって大きなデータを避ける必要があります。
