ホームページ  >  記事  >  バックエンド開発  >  PHP の「正確な」回避策は、正確な 2 桁のお金の計算に信頼できますか?

PHP の「正確な」回避策は、正確な 2 桁のお金の計算に信頼できますか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-07 06:39:02614ブラウズ

Is PHP's `precision` Workaround Reliable for Precise 2-Digit Money Calculations?

浮動小数点の問題に対する PHP PHP.INI 精度の回避策は信頼できますか?

はじめに

浮動小数点演算では、小数を 2 進数で表現する必要があります。分数は正確な表現を持たない場合があります。これにより、丸め誤差が生じる可能性があります。

質問 1:

この回避策により、金額の 2 桁の正確な計算が保証されますか?

回答 1:

いいえ。 PHP の精度設定では、計算中に精度が向上する可能性があるため、正確な 2 桁の計算を保証できません。

質問 2:

回避策が失敗した場合の例:

ini_set('precision', 8);
$a = 5.88; // cost of 1kg
$q = 2.49; // User buys 2.49 kg
$b = $a * 0.01; // 10% Discount only on first kg
echo ($a * $q) - $b; // result: 14.5824 (not precise for money calculations)

質問 3:

2 桁の金額計算に最適な php.ini.precision 値はどれですか?

回答 3:

PHP の精度は次のとおりです。正確な財務計算に推奨されるメトリクスではありません。

簡単なテスト

bcmath、number_format、および減算の使用:

$a = 342349.23;
$b = 341765.07;

ini_set('precision', 20);
echo $a - $b, PHP_EOL; // 584.15999999997438863
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.15999999999996817 (rounding issue)
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.15 (precision set to 20)

ini_set('precision', 14);
echo $a - $b, PHP_EOL; // 584.15999999997
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.16 (precision set to 14)

ini_set('precision', 6);
echo $a - $b, PHP_EOL; // 584.16
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.00 (precision set to 6)

ini_set('precision', 3);
echo $a - $b, PHP_EOL; // 584
echo floatval(round($a - $b, 2)), PHP_EOL; // 584
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 0.00 (precision set to 3)

結論

次の目的でのnumber_format の使用一貫性を保つために、お金の計算を行うことをお勧めします。セント単位で保存することもできます。

更新

質問 1: 精度の回避策は 0..999999.99 の間の数値に対して失敗しますか?

回答 1:

はい、組み合わせが多数あるため、完全なテストは現実的ではありません。

例:

$a = 0.19;
$b = 0.16;
...
$h = $a + $b + ...; // Total value: 0.4

$i = $h - $a - $b - ...; // Result: 1.0408341E-17 (expected: 0.00)

質問 2: 精度の回避策が失敗する時期をどのように推定しますか?

答え 2:

数学的な解決策は存在しますが、それはこの議論の範囲内ではありません。

以上がPHP の「正確な」回避策は、正確な 2 桁のお金の計算に信頼できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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