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 2 Antworten
Letzter Beitrag: Montag, 17. Dezember 2012 16:57 von maharadja

...einen guten Onlineshop für Taufringe? Ich habe bisher Taufringe Direkt gefunden und wollte mal nachhaken, ob der Shop für Taufringe wirklich so ... » mehr

Webentwickler Konferenz in Hamburg

Hallo Zusammen, Am 20./21. Mai findet in Hamburg die erste Developer Conference 2011 statt. Wie der Name bereits verrät, handelt die Konferenz rund ... » mehr

von devcon-hamburg am Dienstag, 12. April 2011 16:50 in PHP - noch nicht beantwortet

bedingte Weiterleitung in Kontaktformularen

Hallo zusammen, ich habe ein kleines Problem: Ich brauche bei der Entwicklung eines Kontaktformulares für eine Website eine bedingte Weiterleitung ... » mehr

von scatha am Donnerstag, 10. März 2011 01:12 in PHP - noch nicht beantwortet

Gesucht: Auslesen einer externen Website

Mein vorhaben ist recht simpel aber ich bin php noob (hoffe das entschuldigt es nen bissl xD) und hab kp wie ichs anfangen soll. Und zwar möchte ich ... » mehr

von HeathenMan am Dienstag, 1. Februar 2011 22:57 in PHP - bisher 1 Antwort
Letzter Beitrag: Donnerstag, 3. Februar 2011 14:43 von alm

Hallo, am einfachsten und kompaktesten kann man das mit einem regulären Ausdruck machen. Einfach mal nach der Funktion preg_match_all suchen und den ... » mehr

Zeilenumbruch in der Bildergalerie-Beschriftung

Hallo, die Bildergalerie mit php und js ist super, jedoch möchte ich gern zu meinen Bildern verschiedene Bemerkungen machen und zwar untereinander, ... » mehr

von Sylma am Mittwoch, 26. Januar 2011 01:13 in PHP - bisher 1 Antwort
Letzter Beitrag: Freitag, 28. Januar 2011 10:16 von alm

Hallo, ich nehme an, dass \n im Beschreibungstext nicht funktioniert aber versuchen kann man es. Ansonsten: Schon mal mit einer UTF-Sequenz ... » mehr

¬ Tutorials



¬ Insolvenzrecht