Logik in der Programmierung

So manch ein Programmierer verzweifelt bei seiner täglichen Arbeit. In den meisten Fällen ist der Grund dafür ein Mensch. Entweder hat der Vorgänger schlechten Code hinterlassen oder man hat selbst bei der Arbeit geschlampt.

Es gibt aber auch Fälle, in denen ist kein Mensch verantwortlich (zumindest nicht direkt), sondern die Programmiersprache selbst. Dazu habe zwei PHP-Beispiele herausgesucht, die zeigen, dass Programmierung nicht immer logisch sein muss.

Beispiel #1: Logische Operatoren

Nehmen wir einmal das folgende, simple PHP-Skript:

<?php
$ampersand = true && false;
$and = true AND false;
var_dump($ampersand == $and);

Bei der ersten Durchsicht des Skripts sollte schnell klar sein, dass in den beiden Variablen $ampersand und $and jeweils false gespeichert sein müsste. Immerhin sind die beiden Abfragen true && false sowie true AND false beide falsch. Das Ergebnis des Skripts sollte also wahr sein, denn beide Variablen enthalten denselben Wert.

Bei Ausführung des Skripts ergibt sich jedoch eine völlig anderes Bild. Die var_dump()-Ausgabe erzeugt nämlich ein bool(false). Aber warum?

Die Erklärung dazu ist einfach, wenn auch nicht unbedingt logisch: In PHP haben Operatoren unterschiedliche Rangfolge. Der &&-Operator hat demnach eine höhere Priorität als der =-Zuweisungsoperator.
Anders verhält es sich mit dem AND-Operator. Dieser kommt in der Rangfolge nach dem =-Zuweisungsoperator. Der Variable $and wird daher der Wert true zugewiesen, ehe der AND-Operator überhaupt greift. Damit sind die Werte der beiden Variablen unterschiedlich.

Beispiel #2: Mathematische Rechnung

In unserer Welt gibt es kaum etwas logischeres als die Mathematik. Sie ist aus der Logik heraus geschaffen worden. Umso schlimmer ist es, dass wir uns als Programmierer nicht immer auf die Korrektheit einer mathematischen Berechnung verlassen können. Nehmen wir dazu folgendes Beispiel-Skript:

<?php
$result = (int) ((0.1 + 0.7) * 10);
var_dump($result);

Ein Mathematiker würde bei dieser einfachen Rechnung nur müde lächeln. 0,1 plus 0,7 ist natürlich 0,8 und das Ganze multipliziert mal 10 ergibt selbstverständlich 8.

Die Ausgabe des obigen Skripts erzeugt dagegen ein int(7), was doch relativ weit von dem erwarteten Ergebnis entfernt liegt. Aber warum ist das so?

Nun, das liegt daran, wie PHP intern mit den Zahlen umgeht. Gespeichert wird das Ergebnis nämlich als 7,99999999…, was wiederum bei der Umwandlung in einen Integer-Wert dazu führt, dass die Zahlen hinter dem Komma abgeschnitten werden.
Umgehen ließe sich das beispielsweise, indem die Umwandlung weggelassen wird (die Ausgabe wäre dann float(8), würde bei einem Vergleich mit einer echten 8 aber ein falsches Ergebnis liefern) oder das Ergebnis vor der Umwandlung noch einmal gerundet:

<?php
$result = (int) round((0.1 + 0.7) * 10);
var_dump($result); // int(8)

Und wer jetzt denkt, dieses Verhalten wäre eine Eigenheit von PHP, den muss ich an dieser Stelle enttäuschen. Auch JavaScript …

console.log(parseInt((0.1+0.7)*10)); // 7

… und Python …

result = int((0.7 + 0.1) * 10)
print result # 7

liefern das gleiche Ergebnis. Vermutlich präsentieren sich auch noch andere Sprachen als unfähig, die ich nicht getestet habe.

Logisch nur auf den zweiten Blick

Ihr seht also, dass in der Programmierung nicht immer alles logisch ist – zumindest nicht auf den ersten Blick. Erst wenn man sich mit den Gründen für ein bestimmtes Verhalten auseinandersetzt, erkennt man die Logik dahinter. Denn wie lautet noch gleich eines von Murphys Gesetzen?

Logic is a systematic method of coming to the wrong conclusion with confidence.

Murphy’s Technology Laws

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.