Gleitkommazahlen
Gleitkommazahlen (auch als "floats", "doubles" oder "reelle Zahlen"
bezeichnet) können anhand einer der folgenden Schreibweisen bezeichnet
werden:
Formell von PHP 7.4.0 an (zuvor waren Unterstriche nicht erlaubt):
Die Größe einer Gleitkommazahl ist plattformabhängig, ein Maximalwert von
circa 1.8e308 mit einer Präzision von ungefähr 14 Dezimal-Nachkommastellen
ist jedoch ein üblicher Wert (64-Bit IEEE-Format).
Warnung
Genauigkeit von Gleitkommazahlen
Gleitkommazahlen haben eine begrenzte Präzision. Obgleich dies vom System
abhängig ist, verwendet PHP üblicherweise das IEEE 754 Double Precision
Format, welches einen maximalen relativen Rundungsfehler in einer
Größenordnung en 1.11e-16 ergibt. Nicht-Elementare arithmetische
Operationen können jedoch größere Fehler hervorrufen und natürlich muss
eine Fortpflanzung des Fehlers berücksichtigt werden, wenn mehrere
Operationen zusammengesetzt werden.
Außerdem gibt es rationale Zahlen, die zur Basis 10 als Gleitkommazahlen
exakt dargestellt werden können, beispielsweise 0.1
oder
0.7
, für die es aber keine exakte Repräsentation als
Gleitkommazahlen zur Basis 2 gibt, welche intern aber unabhängig von der
Größe der Mantisse verwendet wird. Daher können sie nicht ohne einen
geringen Präzisionsverlust in ihre interne binäre Darstellung umgewandelt
werden. Dies kann zu verwirrenden Ergebnissen führen:
floor((0.1+0.7)*10)
wird üblicherweise
7
ergeben statt des erwarteten Ergebnisses von
8
, da die interne Repräsentation etwas ist wie
7.9999999999999991118...
.
Man sollte sich daher niemals bis zur letzten Nachkommastelle auf
Gleitkommazahlen verlassen und Gleitkommazahlen niemals direkt auf
Gleichheit prüfen. Wenn eine höhere Präzision notwendig ist, stehen die
Mathematikfunktionen mit beliebiger Präzision
und die gmp-Funktionen zur Verfügung.
Für eine "einfache" Erklärung steht der Ratgeber
» Floating Point Guide
zur Verfügung, welcher auch den Titel hat "Why don’t my numbers add up?"
Umwandlung in float
Von Strings
Wenn der String
numerisch ist oder
numerisch beginnt, wird er in den entsprechenden Gleitkommawert
umgewandelt, andernfalls wird er in Null (0
)
umgewandelt.
Von anderen Typen
Werte aller anderen Typen werden umgewandelt, indem die Werte zuerst in den
Typ int umgewandelt werden und dieser anschließend zu
float. Weitere Informationen findet man unter
Umwandlung in Integer.
Hinweis:
Da bestimmte Typen ein undefiniertes Verhalten bei der Umwandlung in
int haben, ist dies auch bei der Umwandlung in
float der Fall.
Gleitkommazahlen vergleichen
Wie in der obigen Warnung bereits dargestellt, ist es problematisch,
Gleitkommazahlen auf Gleichheit zu überprüfen, aufgrund ihrer internen
Darstellungsart. Es gibt allerdings Wege, diese Vergleiche von
Gleitkommazahlen anzustellen, die diese Beschränkungen umgehen.
Um Gleitkommazahlen auf Gleichheit zu prüfen, wird eine obere Schranke für
den Rundungsfehler verwendet. Dieser Wert ist bekannt als
Maschinengenauigkeit Epsilon und stellt die kleinste annehmbare Differenz
in der Berechnung dar.
NaN
Einige numerische Operationen können einen Wert ergeben, der durch die
Konstante NAN
dargestellt wird. Dieses Ergebnis
stellt einen undefinierten oder nicht darstellbaren Wert in den
Fließkommaberechnungen dar. Jeder strikte oder nicht strikte Vergleich
dieses Werts mit jedem beliebigen anderen Wert, inklusive sich selbst, nur
nicht true
, wird ein Ergebnis von false
hervorbringen.
Da NAN
eine beliebige Anzahl von anderen Werten
darstellen kann, sollte NAN
nicht mit anderen Werten,
einschließlich sich selbst, verglichen werden. Stattdessen sollte zur
Prüfung is_nan() verwendet werden.