PHP For Beispiel 3: Summenberechnung mit Gleitkommazähler

Die For-Schleife kann nicht nur mit ganzzahligen Zählervariablen verwendet werden. Auch der Einsatz von Gleitkommavariablen als Zähler ist möglich. Im nächsten Beispiel wird eine solche Variable verwendet. Hier wird wieder die Variable zur Speicherung der Summe initialisiert. Nach der Ausgabe einer Zeichenkette, die über die Funktion echo erfolgt, wird eine For-Anweisung mit einem Gleitkommazähler implementiert.

Der Schleifenkopf initialisiert die Zählervariable i mit dem Wert 0. Als Abbruchkriterium dient der Ausdruck i < 1, was bedeutet, dass i solange erhöht wird, bis der dort gespeicherte Wert den Wert 1 erreicht oder gar überschritten hat. Die Schrittweite wird im letzten Teil des For-Statements mit Hilfe des Ausdrucks i+=0.2 festgelegt. Dies bedeutet, dass i nach jedem Schleifendurchgang um 0.2 erhöht wird.

Im Schleifenkörper, der hier mit den geschweiften Klammern eingefasst werden muss, da zwei Anweisungen im Schleifenkörper ausgeführt werden sollen, wird jeweils der in sum gespeicherte Summenwert berechnet und die zum jeweiligen Durchgang berechnete Summe sowie der in i gespeicherte Wert ausgegeben. Nach dem letzten Schleifendurchgang wird ein HTML-Tag zur Darstellung eines Zeilenumbruchs ausgegeben. Zum Schluss wird der Endwert der Variable sum zusammen mit einer beschreibenen Zeichenkette (String) ausgegeben.

<?php
    // Variable zur Summenberechnung zurücksetzen
    $sum = 0;
    // Zeichenkette ausgeben
    echo 'Wertepaare von sum und j: ';
    // Diesmal wird die Schleife von 0 bis < 1 in der Schrittweite 0.2
    // laufen.
    for ($i = 0; $i < 1; $i += 0.2) {
        // Wieder aufsummieren
        $sum += $i;
        // diesmal aber die einzelnen Werte in Wertepaaren ausgeben
        echo '(' . $sum . ', ' . $i . ')';
    }
    // Zeilenumbruch bzw. HTML-Code für einen Zeilenumbruch ausgeben
    echo '<br>';
    // Berechnete Summe ausgeben
    echo 'Summe (Schrittweite 0.2): ' . $sum;
?>

Wertepaare von (sum, j): (0, 0)(0.2, 0.2)(0.6, 0.4)(1.2, 0.6)(2, 0.8)
Summe (Schrittweite 0.2): 2

PHP For Beispiel 4: Abbruchbedingung bei Vergleich mit Float

Das nächste Beispiel unterscheidet sich kaum vom vorangegangenen. Lediglich die Veränderug der Zählervariablen wird hier mit einer anderen Schrittweite angepasst. Der letzte, in der Ausgabe des Scripts weiter unten aufgeführte, Schleifendurchgang erfolgt mit einem Zählerwert von 1 – siehe letztes ausgegebenes Wertepaar (5.5,1).

Aufgrund der formulierten Abbruchbedingung ist dieses Verhalten allerdings nicht erwünscht. Dennoch liefert der Ausdruck für die Abbruchbedingung bei i < 1 den Wert TRUE. Dieses Verhalten hängt mit der internen Speicherung von Werten zusammen. Die Variable i wird als Float-Wert die Konstante 1 allerdings liegt als Integer-Wert vor. Da diese Werte beiderseits intern als binäre Werte gespeichert sind, kann es sein, dass die Werte nicht präzise in binärer Form dargestellt werden können. Bei Integer-Werten ist dies kein Problem, da jeder ganzzahlige Wert in Binärer Darstellung präzise dargestellt werden kann. Anders sieht es bei Gleitkommazahlen aus. Hier kann es zu Ungenauigkeiten bei der binären Speicherung der Daten kommen – vgl. auch 1/3 im Dezimalsystem entspricht als Gleitkommazahl 0,333...; auch hier ist eine genaue Darstellung nicht möglich.

Während dies beim letzten Beispiel möglich war, stösst das folgende Beispiel an diese Genauigkeitsgrenze. Nach dem letzten Durchgang der Schleife enthält i eben nicht wie erwartet den Wert 0.9 und wird auf 1.0 erhöht – was zum Abbruch der Schleifenverarbeitung führt –, sondern einen Wert Nahe 0.9 (etwa 0.8999999...). Dies hat zur Folge, dass die Schleife nocheinmal mit i gleich 1 (genauer gesagt 0.9999999...) ausgeführt wird. Die Abbruchbedingung hat hier etwa die Form 0.999999999 < 1, was TRUE liefert – die Schleife wird einmal häufiger durchlaufen.

<?php
    // Und wieder zurücksetzen
    $sum = 0;
    echo 'Wertepaare von (sum, i): ';
    // Jetzt läuft i von 0 bis < 1 mit einer Schrittweite von 0.1
    for ($i = 0; $i < 1; $i += 0.1) {
        $sum += $i;
        echo '(' . $sum . ',' . $i . ')';
    }
    // und wieder einen Zeilenumbruch
    echo '<br>';
    // Summenwert ausgeben
    echo 'Summe (Schrittweite 0.1): ' . $sum;
?>

Wertepaare von (sum, i): (0,0)(0.1,0.1)(0.3,0.2)(0.6,0.3)(1,0.4)(1.5,0.5)(2.1,0.6) (2.8,0.7)(3.6,0.8)(4.5,0.9)(5.5,1)
Summe (Schrittweite 0.1): 5.5

Verhindert werden kann dieses Verhalten nur durch den Einsatz von Typkonvertierungen oder durch eine vorherige Transformation oder Normierung der Gleitkommawerte. Grundsätzlich sollten Gleitkommazahlen bei Vergleichen – egal ob sie in If-Statements oder als Abbruchbedingung bei Schleifen verwendet werden – nie auf Gleichheit geprüft werden. Im unteren Beispiel wird die Funktion round verwendet, um den in i gespeicherten Wert auf die erste Nachkommastelle zu runden. Round liefert diesen gerundeten Wert zurück und vergleicht ihn mit dem Wert 1.

<?php
    // Summenvariable zurücksetzen
    $sum = 0;
    echo 'Wertepaare von (sum, i): ';
    // Runden auf die erste Stelle nach dem Komma
    for ($i = 0; round ($i, 1) < 1; $i += 0.1) {
        $sum += $i;
        echo '(' . $sum . ',' . $i . ')';
    }
    // Zeilenumbruch
    echo '<br>';
    // Summenwert ausgeben
    echo 'Summe (Schrittweite 0.1): ' . $sum;
?>

Wertepaare von (sum, i): (0,0)(0.1,0.1)(0.3,0.2)(0.6,0.3)(1,0.4)(1.5,0.5)(2.1,0.6)(2.8,0.7) (3.6,0.8)(4.5,0.9)
Summe (Schrittweite 0.1): 4.5

Letzte Posts aus unserem Forum

Wer kennt .....

Hallo erstmal wer kennt von euch einen WEbprogrammieren,desginer der mir eine Seite erstellen kann ,Communityportal sowas in der art wie ... » mehr

von NCWebmaster am Mittwoch, 7. Oktober 2009 00:32 in PHP - bisher 1 Antwort
Letzter Beitrag: Mittwoch, 7. Oktober 2009 13:26 von kalle

Hallo auch, da gibt es sicher viele die das machen würden, allerdings deutlich weniger die es auch tatsächlich machen könnten - noch einmal weniger ... » mehr

oh Mann

Hallo erstmals..... also ich kenn mich ja nicht so aus, aber ich denke die Menschheit fliegt auf den Mond, dann müsste es auch eine Lösung für mein ... » mehr

von Dummbazz am Dienstag, 24. Februar 2009 15:11 in PHP - bisher 2 Antworten
Letzter Beitrag: Mittwoch, 25. Februar 2009 11:48 von Dummbazz

Danke für die aufmunternde Worte... ... » mehr

counter auch ohne datenbank?

tach auch, ich habe nach einem besucherzähler gesucht, der auf meiner seite anzeigt, wieviele besucher sich dort aufhalten. allerdings habe ich ... » mehr

von marcel am Montag, 8. Dezember 2008 12:21 in PHP - bisher 1 Antwort
Letzter Beitrag: Montag, 8. Dezember 2008 13:34 von alm

Hallo, sicher kann die Counter-Klasse so umgeschrieben werden, dass sie auch ohne Datenbankanbindung funktioniert. Allerdings würde das einer neuen ... » mehr

DAten speichern und abfragen

Hallo an Alle! Hoffe, dass ich hier im richtigen Forum bin. Vielleicht kann mir jemand einen Tip geben. Ich möchte auf meiner Webpage ein Formular ... » mehr

von muenchner am Samstag, 12. Juli 2008 18:31 in PHP - bisher 1 Antwort
Letzter Beitrag: Montag, 14. Juli 2008 08:49 von alm

Hallo, ich bin mir nicht sicher, wie das jetzt gemeint ist! Geht es um die Frage: Sollen die Optionen des Forumlars (die einzelnen Checkboxen) in ... » mehr

Tutorials :: PHP & MySQL - Problem

Hi, zunächsteinmal danke für das Tutorial: ... » mehr

von migges am Montag, 2. Juni 2008 12:05 in PHP - bisher 3 Antworten
Letzter Beitrag: Dienstag, 3. Juni 2008 11:45 von alm

Das mit den Oder-Operatoren wundert mich ein wenig... Welchen Fehler hat der Interpreter an diesen Stellen ausgegeben? Ich habe bislang mit ... » mehr

¬ Tutorials



¬ Insolvenzrecht