tuerchen 01 · 1. Dezember
Der Glühwein-Rechner
Was gibt der Code aus?LeichtPHP 8.4
Aufgabe
Zum Aufwärmen ein Klassiker mit Haken: Zwei Tassen Glühwein, eine mit 0,1 l und eine mit 0,2 l. Macht zusammen 0,3 l – oder? Was gibt dieses Skript genau aus?
<?php
$summe = 0.1 + 0.2;
echo ($summe == 0.3 ? 'gleich' : 'ungleich')
. ' | ' . $summe
. ' | ' . var_export($summe, true);
- agleich | 0.3 | 0.3
- bungleich | 0.3 | 0.30000000000000004richtig
- cungleich | 0.30000000000000004 | 0.30000000000000004
- dungleich | 0.3 | 0.3
Tipp anzeigenTipp ausblendenkostet keine Punkte
Gleitkommazahlen (IEEE 754) sind selten exakt. Lies in der php.ini-Doku nach, was precision und serialize_precision steuern – und wer sie benutzt.
Mitraten geht mit deinem kostenlosen Entwicklerkonto
Lesen darf jeder. Punkte, Bestenliste und Preise gibt es nur mit Konto.
Auflösung
Richtig ist b.
0,1 und 0,2 lassen sich im Binärsystem nicht exakt darstellen (IEEE 754). Die Summe ist 0.30000000000000004, also schlägt == gegen 0.3 fehl: ungleich.
Der Trick sitzt in der Mitte: echo wandelt Floats mit der ini-Einstellung precision (Standard 14 Stellen) in einen String um und zeigt deshalb brav 0.3. var_export() und var_dump() nutzen dagegen serialize_precision = -1 und geben die kürzeste Darstellung aus, die den Wert exakt wiederherstellt – da ist der Rundungsfehler sichtbar.
Für Geld rechnest du deshalb in Cent (int) oder mit bcmath. Floats vergleichst du mit einer passenden Toleranz, z. B. abs($a - $b) < 1e-9, oder relativ: abs($a - $b) <= PHP_FLOAT_EPSILON * max(abs($a), abs($b)) – PHP_FLOAT_EPSILON allein ist nur der Abstand zur nächsten Zahl bei 1.0 und taugt nicht als absolute Toleranz. Mehr dazu: php.net – Gleitkommazahlen.