PHP und einfache Mathematik.

Also entweder bin ich zu dämlich zum Rechnen oder PHP interpretiert irgendwelche Anweisungen nicht so wie ich das verstehe, daher mal ein kleines Beispiel mit der Ausgabe. Vielleicht sehe ich den Wald auch vor lauter Bäumen nicht…

<?
	$a = (((20 - 19.5) + 3) * 10);
	echo "a: " . $a . "\r";
	if ($a <> 35)
	{
   	echo "Diff a: " . (35 - $a) . "\r";
	}
	
	$c = (((20 - 19.1) + 3) * 10);
	echo "c: " . $c . "\r";
	if ($c <> 39.0)
	{
   	echo "Diff c: " . (37 - $c) . "\r";
   	echo "Diff c: " . (38 - $c) . "\r";
   	echo "Diff c: " . (39 - $c) . "\r";
   	echo "Diff c: " . (40 - $c) . "\r";
   	echo "Diff c: " . (41 - $c) . "\r";
	}
?>

Ausgabe: (Hier würde ich nach meinem Taschenrechner keine Ausgaben mit Diff erwarten…)

a: 35
c: 39
Diff c: -2
Diff c: -0.99999999999999
Diff c: 1.4210854715202E-014
Diff c: 1
Diff c: 2

Jemand eine Idee?

Hallo Tobias,
ich bin zwar keine PHP-Leuchte aber ich kenne nur diese Zeichen:

== (genau gleich)
!= (ungleich / ist nicht)
<= (kleiner oder genau gleich)
>= (größer oder genau gleich)
< (kleiner)
> (größer)

<> kenne ich leider nicht.:confused:

Gruß
Christian

Hallo Tobias,

Du bist da über eine ganz alltägliche Hürde gestolpert.

Genauso wie man im Dezimalsystem den Bruch 1/3 nicht beliebig exakt darstellen kann (dez: 0.333333…), da er unendlich viele Nachkommastellen hat, kann man im Binärsystem den Bruch 1/10 (dez: 0.1) nicht darstellen. In Deinem Beispiel wird also die Zahl 19.1 nur mit endlicher Genauigkeit im Binärsystem des Computers abgelegt. Daher entstehen in solchen Fällen immer Fehler, die dann mitgeschleppt werden.

Die Folge davon ist, man muss ein paar grundsätzliche Regeln beachten. Die wichtigste lautet:

Float-Werte sollten niemals auf (Un-)Gleichheit (==, <>) geprüft werden, sondern immer auf größer (>) oder kleiner (<)!

Gruß
HJH

@Bussard013
!= und <> sind in der Funktionsweise identisch, siehe PHP: Vergleichs-Operatoren - Manual

So alltäglich kann es ja nicht sein, das ich erst nach grob 15 Jahren darüber gestolpert bin :wink:
Aber hab das Ganze gerade auch mal in C# nachvollzogen. Rechnet auch nicht besser, aber immerhin sind die Ausgaben durchgehend falsch.
Was mich ja noch so wundert ist das die Ausgabe des Wertes richtig ist und erst bei einer Berechnung die komischen Werte rauskommen.
Ist auf jeden Fall ab jetzt im Hinterkopf notiert und ab jetzt wird einfach immer auf x-Stellen gerundet.
Denn trotz allem muss ich einen Vergleich auch Ungleichheit machen, da ich nur bei einem geänderten Wert Berechnungen ausführen will.
Immerhin ist aber (1 / 3) == (2 / 6) :rolleyes: