Bug in php ?

BigDundee

Mitglied
Hallo,

kann mir jemand verraten warum folgendes Script keinen Treffer liefert?
PHP:
for ($i = 0; $i < 3; $i += 0.1)
{
  if ($i == 1)
  {
    print "--Treffer!--";
  }
  print $i . "<BR>";
}

Sobald ich die Schrittweite nur geringfügig verändere nach oben hin, also zB += 0.100001 funktioniert das.

Ich bin gerade bisl ratlos.
getestet in PHP Version 4.4.1 und PHP Version 5.0.3
 
Ist ja nen Ding :-)

Ich hab mal im PHP-Handbuch nachgeschaut...da steht folgendes:
Fließkomma Präzision
Es ist ziemlich normal, dass einfache Dezimalzahlen wie 0.1 oder 0.7 nicht in ihre internen binären Entsprechungen konvertiert werden können, ohne einen kleinen Teil ihrer Genauigkeit zu verlieren. Das kann zu verwirrenden Ergebnissen führen. So wird floor((0.1 + 0.7) * 10) normalerweise 7 statt des erwarteten Wertes 8 zurück geben (als Ergebnis der internen Entsprechung von 7.9999999999....

Das gründet sich auf die Tatsache, dass es unmöglich ist, manche Dezimal-Zahlen durch eine endliche Anzahl an Nachkomma-Stellen darzustellen. Dem Wert 1/3 entspricht z.B. der interne Wert von 0.3333333. . ..

Deshalb sollten Sie nie den Ergebnissen von Fließkomma-Operationen bis auf die letzte Nachkomma-Stelle trauen und nie solche auf Gleichheit prüfen. Benötigen Sie wirklich eine größere Genauigkeit, sollten sie die mathematischen Funktionen beliebiger Genauigkeit oder die Gmp Funktionen benutzen.
Es scheint also, als sei für PHP beim Vergleich 0.9 + 0.1 nicht 1

So herum gehts besser:
PHP:
<?php

for ($i = 0; $i < 3; $i += 0.1)
{
  if (!bccomp ($i,1,1))
  {
    print "--Treffer!--";
  }
  print $i . "<BR>";
} 
?>
 
Hallo,
danke für den Tipp :o)

Wenn ich nu noch rausbekomme warum mir
PHP Version 4.3.8 da Call to undefined function: bccomp() liefert während es unter PHP Version 4.4.1 und PHP Version 5.0.3 geht bin ich zufrieden.

Weil natürlich ist PHP Version 4.3.8 das System auf dem es laufen soll :o)
 
Oft gibt man sich auch damit zufrieden, dass eine Fließkommazahl bis auf einen kleinen Unterschied mit der gesuchten Zahl übereinstimmt:
PHP:
<?php

define('EPSILON', 0.0001);

for ($i = 0; $i < 3; $i += 0.1) {
	if (abs($i - 1) < EPSILON) {
		print "--Treffer!--";
	}
	print $i . "<BR>";
}

?>
 
Zurück