Einfache Rechnung in PHP wird als Falsch ausgegeben?!
dasevian12
- php
0 dedlfix0 dasevian120 dedlfix
Hallo ich melde mich bei euch mit einem Problem, das so simple sein kann, dass ich schon wieder ratlos bin.
Ich habe eine einfache Rechnung in PHP. Zuvor hole ich Werte aus mehreren Rechnungen und MYSQL Abfragen und speicher sie in die Variabeln $sumkomuliert und $konto_user[guthb]. Nun verfleiche ich diese Beiden Werte in einer einfachen Rechnung:
if($sumkomuliert==$konto_user['guthb']) {
$error="$sumkomuliert==$konto_user[guthb] RICHTIG <br>";
} else {
$error="$sumkomuliert==$konto_user[guthb] FEHLER <br>";
}
echo $error;
Das ganze durchläuft eine Whileshleife, weil ich die Werte aus einer Datenbank hole um sie zu vergleichen, als Ausgabe bekomme ich nun folgendes.
1.88==6.48 FALSCH
34.12==34.12 RICHTIG
1.55==1.55 RICHTIG
2.45==2.45 FALSCH
Aber wie kann das sein? Ich habe keinen Tippfehler unten bei 2.45==2.45 kommt Falsch raus und ich habe keine Ahnung warum.
Wäre für Hilfe sehr dankbar!
Hi!
$sumkomuliert
Kumulieren schreibt sich das.
2.45==2.45 FALSCH
Aber wie kann das sein?
Bitte die Werte mit var_dump() ausgeben lassen.
Lo!
Hi!
$sumkomuliert
Kumulieren schreibt sich das.
2.45==2.45 FALSCH
Aber wie kann das sein?Bitte die Werte mit var_dump() ausgeben lassen.
Lo!
Ich achte bei Variabeln leider nicht auf die Rechtschreibung. Bin ja nur Ich der sie liest :)
Ich habe den Fehler derweil gefunden, ich weiß zwar nicht wie er zustande kamm, aber ein einfaches stripslashes() hat mein Problem gelöst.
Hi!
Ich habe den Fehler derweil gefunden, ich weiß zwar nicht wie er zustande kamm, aber ein einfaches stripslashes() hat mein Problem gelöst.
Bei den Werten, die aus dem DBMS kommen? Dann hast du beim Eintragen was falsch gemacht. Zudem wüsste ich nicht, was bei 2.45 ein Slash zu tun hätte.
Lo!
Hi,
Ich habe den Fehler derweil gefunden, ich weiß zwar nicht wie er zustande kamm, aber ein einfaches stripslashes() hat mein Problem gelöst.
Bei den Werten, die aus dem DBMS kommen? Dann hast du beim Eintragen was falsch gemacht. Zudem wüsste ich nicht, was bei 2.45 ein Slash zu tun hätte.
eine (zugegebenermaßen) wilde Vermutung meinerseits:
aus der Datenbank kommt nicht 2.45, sondern dies ist die gerundete Version nach der Ausgabe als String.
Dann würde folgendes passieren: beim Vergleich hat man z.B. (Werte ausgedacht) 2.45000000001 und 2.45, welche ungleich sind. Bei der Ausgabe (insb. durch die implizite Stringkonvertierung) wird nicht 2.4500000000001, sondern nur 2.45 ausgegeben (Rundung).
Daher wäre dein Hinweis, mit var_dump die Variable auszugeben, sinnvoll.
stripslashes arbeitet mit Strings und nicht mit floats und könnte diese Rundung ebenfalls implizit durchführen.
Beispiel:
$var = 2.45000000000001;
$var1 = 2.45;
if ($var == $var1) {
echo "$var==$var1 RICHTIG\n";
} else {
echo "$var==$var1 FALSCH\n";
}
$var = stripslashes($var);
if ($var == $var1) {
echo "$var==$var1 RICHTIG\n";
} else {
echo "$var==$var1 FALSCH\n";
}
Bis die Tage,
Matti
Hi,
Beispiel:
$var = 2.45000000000001;
$var1 = 2.45;if ($var == $var1) {
echo "$var==$var1 RICHTIG\n";
} else {
echo "$var==$var1 FALSCH\n";
}$var = stripslashes($var);
if ($var == $var1) {
echo "$var==$var1 RICHTIG\n";
} else {
echo "$var==$var1 FALSCH\n";
}
Ausgabe bei mir:
matti@obiwan:~$ php ttt.php
2\.45==2.45 FALSCH
2\.45==2.45 RICHTIG
matti@obiwan:~$ php -v
PHP 5.3.4 (cli) (built: Dec 15 2010 12:15:07)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
matti@obiwan:~$
Bis die Tage,
Matti
--
[Webapplikationen in C++ entwickeln](http://tntnet.org/)
Hi,
und um mein Posting-Triple abzuschließen:
"man" vergleicht floats nicht direkt miteinander. Floats (bzw. allgemein die Fließkommadarstellung) sind nicht genau (siehe z.B. Wikipedia: Gleitkomma).
Im Internet sind viele "korrekte" Wege aufgezeigt, Fließkommazahlen direkt miteinander zu vergleichen.
Üblich wäre eine erlaubte Fehlertoleranz
$err = 1E-3;
if (abs($var - $var1) < $err) {
echo "Zahlen sind fast gleich\n";
}
oder der ganze Verzicht auf Fließkommazahlen.
So könnte man Geldbeträge statt in Euro mit Cents als Nachkommastellen und Cent abspeichern und dies dann als integer speichern (wobei man trotzdem auf Divisionen achten muss, damit man nicht implizit floats erhält). Allgemein ist Division recht gefährlich, es ist meist besser, darauf zu verzichten und beim Vergleich jeweils die Gegenseite mit den ursprünglichen Nennern zu multiplizieren.
Bis die Tage,
Matti
Hi!
So könnte man Geldbeträge statt in Euro mit Cents als Nachkommastellen und Cent abspeichern und dies dann als integer speichern (wobei man trotzdem auf Divisionen achten muss, damit man nicht implizit floats erhält).
Nein. Da das ein sehr häufiges Problem ist, ist es bereits gelöst. Es gibt einen speziellen Datentyp, der solche Werte exakt und ohne das Problem der Fleißkommazahlenungenauigkeiten speichern kann.
Zudem kann es auch sein, dass dein Test nicht relevant ist, da - ich hab eben nochmal nachgeschaut - auch Interger- und Float-Werte als String in PHP landen.
Lo!