Abschnitt 2 · Lektion 3
Zahlen
Zahlen schreibst du in PHP einfach hin, ohne Anführungszeichen. Was du dabei wissen musst, passt in zwei Sätze und eine Warnung. Die Warnung ist der Grund, warum diese Lektion eine eigene ist.
Ganze und gebrochene Zahlen
PHP kennt zwei Sorten. Ganze Zahlen heißen int, gebrochene heißen float. Getrennt wird mit einem
Punkt, nie mit einem Komma: 4.5 ist eine Zahl, 4,5 wäre etwas ganz anderes.
<?php
$menge = 3;
$preis = 4.5;
$summe = $menge * $preis;
echo "Menge: $menge\n";
echo "Preis: $preis\n";
echo "Summe: $summe\n"; Du musst nirgends ankündigen, welche Sorte du willst. 3 ist ein int, 4.5 ist ein float, und
sobald eine gebrochene Zahl in der Rechnung vorkommt, ist das Ergebnis auch gebrochen. Deshalb steht
in $summe am Ende 13.5 und nicht 13.
Diese Bequemlichkeit hat eine Kehrseite, die man ihr nicht ansieht.
<?php
$glatt = 4 / 2;
$krumm = 5 / 2;
$ganz = intdiv(5, 2);
$rest = 5 % 2;
echo "4 / 2 ergibt $glatt\n";
echo "5 / 2 ergibt $krumm\n";
echo "intdiv(5, 2) ergibt $ganz\n";
echo "5 % 2 ergibt $rest\n"; 4 / 2 ergibt eine ganze Zahl, 5 / 2 eine gebrochene. Die Division entscheidet also von Fall zu
Fall, was herauskommt, und in der Ausgabe stehen dann 2 und 2.5 nebeneinander, ohne dass man
erkennt, dass da zwei verschiedene Sorten am Werk sind. Die nächste Lektion zeigt dir, wie du
nachsiehst.
Wenn du ausdrücklich ganzzahlig rechnen willst, gibt es zwei Werkzeuge. intdiv(5, 2) teilt und
wirft den Rest weg, 5 % 2 liefert genau diesen Rest. Beide brauchst du öfter, als du jetzt denkst:
Sekunden in Minuten umrechnen, eine Liste auf Seiten aufteilen, jede zweite Zeile einfärben.
Die Rechnung, die nicht aufgeht
Und jetzt die Sache, wegen der diese Lektion existiert.
<?php
$summe = 0.1 + 0.2;
$rest = 0.1 + 0.2 - 0.3;
echo "0.1 + 0.2 ergibt $summe\n";
echo "0.1 + 0.2 - 0.3 ergibt $rest\n"; Zwei Zeilen, die sich widersprechen. Die erste sagt, 0.1 + 0.2 sei 0.3. Die zweite zieht 0.3
wieder ab und behauptet, es bleibe etwas übrig: 5.5511151231258E-17. Das ist die Schreibweise für
eine sehr kleine Zahl, hier eine Null, danach sechzehn weitere Nullen, und dann erst kommen Ziffern.
Winzig, aber eben nicht null.
Der Grund liegt nicht bei PHP. Ein Rechner speichert gebrochene Zahlen zur Basis zwei, und ein
Zehntel hat dort keine exakte Schreibweise, so wie ein Drittel zur Basis zehn keine hat: 0,3333...
hört nie auf. Irgendwo muss abgeschnitten werden, und dieser Schnitt ist der Rest, den du oben siehst.
Jede Sprache mit diesem Zahlenformat macht das so, JavaScript, Python und Java eingeschlossen.
Warum sagt echo dann trotzdem 0.3? Weil es vor der Ausgabe rundet, auf vierzehn geltende
Ziffern. Der Fehler liegt weit dahinter und fällt der Rundung zum Opfer. Die Anzeige beschönigt also,
die Rechnung nicht. In der nächsten Lektion siehst du den Wert ungeschönt, und dann ergibt dieses
Beispiel rückwirkend Sinn.
Zwei praktische Folgen. Die erste: Prüf nie zwei gebrochene Zahlen auf Gleichheit. Die Rechnung kann stimmen und die Prüfung trotzdem nein sagen. Mehr dazu in Lektion 3.6. Die zweite betrifft Geld, und die ist wichtiger.
Bei Geld rechnest du in Cent
Ein Betrag ist keine gebrochene Zahl, sondern eine Anzahl von Cent. Wenn du so denkst, verschwindet das ganze Problem, denn ganze Zahlen rechnet PHP exakt.
<?php
$preisCent = 1999;
$menge = 3;
$summeCent = $preisCent * $menge;
$euro = intdiv($summeCent, 100);
$cent = $summeCent % 100;
$anzeige = number_format($summeCent / 100, 2);
echo "Summe in Cent: $summeCent\n";
echo "Ganze Euro: $euro\n";
echo "Restliche Cent: $cent\n";
echo "Fertig formatiert: $anzeige\n"; 19,99 Euro sind 1999. Drei davon sind 5997, und daran ist nichts ungenau. Erst ganz am Ende,
wenn ein Mensch die Zahl sehen soll, machst du daraus einen Betrag. Dafür ist number_format da: Das
zweite Argument sagt, wie viele Nachkommastellen du willst, und du bekommst sie garantiert, auch wenn
sie 00 lauten. Ein echo allein würde aus 59.9 nur 59.9 machen, und das sieht auf einer
Rechnung falsch aus.
number_format schreibt englisch, mit Punkt vor den Cent. Wie du daraus die deutsche Schreibweise mit
Komma und Tausenderpunkt machst, steht in Lektion 3.4. Für den Moment reicht die Form mit den zwei
Nachkommastellen, und genau die brauchst du gleich in der Aufgabe.
Zum Mitnehmen
PHP unterscheidet ganze Zahlen von gebrochenen und wechselt zwischen beiden von selbst. Beim Rechnen mit Geld ist genau das die Falle, und sie hat eine einfache Lösung.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.