Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL- und PHP-Dezimalgenauigkeit falsch

Von ein Artikel, den ich für Authorize.Net geschrieben habe :

Eins plus eins gleich zwei, oder? Wie wäre es mit 0,2 plus 1,4 mal 10? Das entspricht 16, richtig? Nicht, wenn Sie mit PHP (oder den meisten anderen Programmiersprachen) rechnen:

echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!

Dies liegt daran, wie Gleitkommazahlen intern gehandhabt werden. Sie werden mit einer festen Anzahl von Dezimalstellen dargestellt und können zu Zahlen führen, die sich nicht ganz wie erwartet aufsummieren. Intern ergibt unser 0,2 plus 1,4 mal 10 Beispiel ungefähr 15,9999999998 oder so. Diese Art der Mathematik ist in Ordnung, wenn Sie mit Zahlen arbeiten, die nicht genau sein müssen, wie Prozentsätze. Aber bei der Arbeit mit Geld kommt es auf Präzision an, da sich ein Penny oder ein Dollar, der hier oder da fehlt, schnell summiert, und niemand mag es, bei fehlendem Geld zu kurz zu kommen.

Die BC Math-Lösung

Glücklicherweise bietet PHP die BC-Math-Erweiterung an Das heißt:"Für Mathematik mit beliebiger Genauigkeit bietet PHP den Binärrechner, der Zahlen jeder Größe und Genauigkeit unterstützt, die als Zeichenfolgen dargestellt werden." Mit anderen Worten, Sie können mit dieser Erweiterung präzise mit Geldwerten rechnen. Die BC Math-Erweiterung enthält Funktionen s, mit denen Sie die gängigsten Operationen präzise ausführen können, einschließlich Addition , Subtraktion , Multiplikation , und division .

Ein besseres Beispiel

Hier ist das gleiche Beispiel wie oben, aber mit der Funktion bcadd(), um die Berechnungen für uns zu erledigen. Es braucht drei Parameter. Die ersten beiden sind die Werte, die wir addieren möchten, und die dritte ist die Anzahl der Dezimalstellen, auf die wir genau sein möchten. Da wir mit Geld arbeiten, setzen wir die Genauigkeit auf zwei Dezimalstellen.

echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.