Heim  >  Artikel  >  Backend-Entwicklung  >  Problem mit der PHP-Präzisionsberechnung

Problem mit der PHP-Präzisionsberechnung

单线程
单线程Original
2020-05-07 15:35:03161Durchsuche

PHP-Präzisionsberechnungsproblem

Werfen wir einen Blick auf ein interessantes Phänomen in PHP: var_dump( intval(0.58 * 100 ) ); Raten Sie mal, welches Ergebnis dieser Code ausgeben wird?

Das Ausgabeergebnis ist 57, nicht 58

Warum ist das so? Dies alles wird durch Gleitkomma-Arithmetik verursacht.
Eigentlich handelt es sich bei diesen Ergebnissen nicht um Sprachfehler, sondern um das Implementierungsprinzip der Sprache. Alle Zahlen in js werden als Zahl vereinheitlicht, einschließlich Ganzzahlen, die eigentlich alle doppelte Typen sind.

Und PHP unterscheidet zwischen int und float. Unabhängig von der Sprache gibt es ähnliche Probleme, solange es sich um Gleitkommaoperationen handelt. Sie müssen daher bei der Verwendung darauf achten.

Gleitkommazahlen, beispielsweise mit einer Länge von 64 Bit (doppelte Genauigkeit), werden durch 1 Vorzeichenbit (E), 11 Exponentenbits (Q) und 52 Mantissen (M) (64) dargestellt Bits insgesamt).

Vorzeichenbit: Das höchste Bit stellt das Vorzeichen der Daten dar, 0 steht für eine positive Zahl und 1 steht für eine negative Zahl.

Exponentenbit: Stellt die Potenz der Daten zur Basis 2 dar, und der Exponent wird durch einen Offset-Code dargestellt.

Mantisse: Stellt die signifikanten Stellen nach dem Dezimalpunkt der Daten dar.

Die wichtigsten Punkte hier sind die Darstellung von Dezimalzahlen im Binärformat. Ich werde hier nicht näher darauf eingehen binäre Darstellung, 0,58 ist ein unendlicher Wert (die Zahlen unten lassen die implizite 1 weg). von 0,57 ist grundsätzlich (52 Bits): 0 01000111101011100001010001111010111000010100011110

Die Binärzahlen der beiden, wenn sie nur durch diese 52 Bits berechnet werden, sind:

0,58 -> 0,579999999 999999960,57 -> 0,56999999999999999

Was 0,58 * 100 betrifft, denken wir nicht im Detail über die spezifische Multiplikation von Gleitkommazahlen nach. Wir betrachten es nur vage mit Kopfrechnen ... 0,58 * 100 = 57,999999999

Dann wenn Wenn Sie es intvalieren, wird es natürlich 57 sein...

Es ist ersichtlich, dass der Kernpunkt dieses Problems ist: „Sie scheinen eine endliche Dezimalzahl zu haben, aber in der binären Darstellung ist sie unendlich.“ der Computer"

Es gibt eine Ungenauigkeit bei +-*%/ im PHP-Gleitkommatyp

Wir können das Problem ungenauer Gleitkommaoperationen durch die folgenden häufig verwendeten Hochkommaoperationen lösen: Präzisionsfunktionen:

bcadd – Addiere zwei hochpräzise Zahlen bccomp – Vergleiche zwei hochpräzise Zahlen und gebe -1, 0, 1  zurück

bcdiv – Dividieren Sie zwei hochpräzise Zahlen

bcmod – Ermitteln Sie den Rest einer hochpräzisen Zahl

bcmul – Multiplizieren Sie zwei hochpräzise Zahlen

bcpow – Ermitteln Sie die Potenz von a hochpräzise Zahl

bcpowmod – Ermitteln Sie die Potenz einer hochpräzisen Zahl und modulieren Sie sie, sehr häufig in der Zahlentheorie verwendet

bcscale – konfigurieren Sie die Standardanzahl von Dezimalstellen, äquivalent zu „ scale=" in Linux bc

bcsqrt – finde die Quadratwurzel einer hochpräzisen Zahl

bcsub – kombiniere zwei hochpräzise Zahlen Less

Das obige ist der detaillierte Inhalt vonProblem mit der PHP-Präzisionsberechnung. 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