Heim  >  Artikel  >  Backend-Entwicklung  >  Ist PHPs „Präzisions'-Workaround für präzise zweistellige Geldberechnungen zuverlässig?

Ist PHPs „Präzisions'-Workaround für präzise zweistellige Geldberechnungen zuverlässig?

Linda Hamilton
Linda HamiltonOriginal
2024-11-07 06:39:02611Durchsuche

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

Kann ich mich auf PHP PHP.INI Precision Workaround für Gleitkomma-Probleme verlassen?

Einführung

Gleitkomma-Arithmetik beinhaltet die Darstellung von Bruchzahlen als Binärzahlen Brüche, die möglicherweise keine exakte Darstellung haben. Dies kann zu Rundungsfehlern führen.

Frage 1:

Kann diese Problemumgehung genaue zweistellige Berechnungen für Geld gewährleisten?

Antwort 1:

Nein.PHP-Präzisionseinstellungen können keine präzisen zweistelligen Berechnungen garantieren, da die Präzision während der Berechnungen erhöht werden kann.

Frage 2:

Beispiel dafür, wann die Problemumgehung fehlschlägt:

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)

Frage 3:

Welcher php.ini.precision-Wert eignet sich am besten für zweistellige Geldberechnungen?

Antwort 3:

PHP-Präzision ist Keine empfohlene Metrik für präzise Finanzberechnungen.

Einfacher Test

Verwendung von bcmath, Zahlenformat und Subtraktion:

$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)

Schlussfolgerung

Verwendung von Zahlenformat für Aus Konsistenzgründen werden Geldberechnungen empfohlen. Auch das Speichern in Cent ist eine Option.

Update

Frage 1: Schlägt der Präzisions-Workaround für Zahlen zwischen 0..999999,99 fehl?

Antwort 1:

Ja, aufgrund der großen Anzahl an Kombinationen ist ein vollständiger Test unpraktisch.

Beispiel:

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

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

Frage 2: Wie kann man abschätzen, wann die Präzisions-Umgehung fehlschlägt?

Antwort 2:

Mathematische Lösungen gibt es, aber sie fallen nicht in den Rahmen dieser Diskussion.

Das obige ist der detaillierte Inhalt vonIst PHPs „Präzisions'-Workaround für präzise zweistellige Geldberechnungen zuverlässig?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn