Kann PHP nicht richtig rechnen?

Der Titel ist etwas eigenartig, aber so kommt es mir vor.
Wenn ich Zahlen addiere und subtrahiere, die nur eine Nachkommastelle haben, wie kann es dann sein, dass dann mehr Nachkommastellen herauskommen?
Ein Beispiel

All diese Variablen haben nur eine Nachkommastelle


Ich habe extra das Profil rausgenommen (begrenzt auf eine Nachkommastelle) um den „richtigen“ Wert zu sehen.

Die Werte haben auch in der Vorschau (hoover über der ID) den richtigen Wert.
Wenn ich diese Berechnung durchführe, kommt statt „7,1“, „7,0999999“ heraus

Sollte ich wo einen Fehler haben, bitte her damit. Ansonsten finde ich das eher bedenklich.
Ebenso habe ich alle Werte in der Konsole noch einmal mit dem aktuell angezeigten Wert überschrieben. Keine Änderung.

Das liegt an PHP - weniger an Symcon.
Hier werden ein paar Beispiele gegeben:
https://medium.com/@dotcom.software/floating-dangers-in-php-c4a2220bd8dc

Wäre natürlich möglich eine Library einzuführen, welche diese Probleme umgeht.

Grüße
Stefan

Hi,
es liegt auch nicht wirklich an PHP sondern am IEEE-Format der Floatzahlen. 7.1 gibt es in IEEE nicht sondern es wird als 7.099999904632568359375 gespeichert. Die etwas Älteren erinnern sich vielleicht daran das Excel mal aus 10/3*3=9.9999999 machte.

Ralf

Ok, verstehen muss ich das jetzt nicht. Also ich verstehe schon die Hintergründe…aber es sollte doch mathematisch richtig sein.
Egal.
Ich dachte ich kann es überlisten. Denkste.


Mit number_format($wert,1) funktioniert es. Dann stimmt es zumindest.

Habe es dann unter Skripte verschoben und aus IPS PHP gemacht :slight_smile:
Tip: Da echo immer eine Konvertierung von bool/int/float zu string macht, würde ich zum testen eher zu var_dump($var) raten.
Michael

Ok, aber ändert nichts am Fehler :wink:

Der keiner ist, wie du hoffentlich oben gelesen hast :wink:
Michael

Hi,
das Problem ist das praktisch kein Computer mit Zahlen zur Basis 10 arbeitet sondern fast alle nehmen Basis 2 eben das IEEE-Format. Irgendwann hat man dieses Format gegenüber BCD (binär coded decimal) bevorzugt weil der Wertebereich deutlich größer ist.

Es ist kein Fehler sondern die harte Realität bzw. das wirkliche Leben :rofl:

Ralf

Moin,

wenn du im Forum nach Epsilon suchst wirst du weitere Informationen zum Umgang mit Floating Point Variablen bekommen. Und wie andere User bereits geschrieben haben ist es kein Fehler sondern ein bekannter Effekt der auch bei Vergleichen solcher Variablen stets zu beachten ist (Epsilon Umgebung).

Gruß
Hans

Das erkläre mal allen Mathematiklehrern :rofl:
Danke für den Hinweis. number_format liefert einen String. Ich habs jetzt auf round geändert. Damit passt es hoffentlich besser.

Nochmal der Computer rechnet richtig. Du speicherst das Ergebnis nur nicht hochauflösend genug.

Wenn du 1 * 1,1 rechnest kommt da 1,1 raus. Sobald du es aber in einem integer speicherst, wird das wider 1 draus.

Deswegen rechnet man niemals mit floats wenn das Ergebnis danach stimmen soll.

Das ist auch der Grund warum es Math-Libs gibt. Dieser Fehler wird leider immer wieder gemacht. Wie häufig habe ich es schon gesehen das eine Finanzbuchhaltung mit floats arbeitet und man sich dann wundert warum die Buchhaltung nicht stimmt.

Es hat übrigens auch Vorteile das floats schneller gerechnet werden können. Baus du ein Computer spielt und renderst Bilder reicht die Genauigkeit und und du freust dich über mehr fps

Das mag alles stimmen, nur kann ich in IPS mit Interger keine Nachkommastellen rechnen.
ICH speichere gar nichts irgendow ab. Ich definiere Variablen in IPS. Und zu dieser Variable möchte ich 0.1 addieren und es soll nicht 0.09999999 herauskommen. So einfach ist das. Und das war meine Eingangsfrage.

Eigentlich schon und das wird auch gerne gemacht. Man rechnet mit zB.710 um 7,10 abzubilden. Aber du kannst auch mit der Mathelibrary GMP von PHP rechnen.

Aber in der Regel ist das alles übertrieben. Normal macht man ein runden auf die nachkommastelle die man braucht. Dann wird da so oder so die passende Zahl draus.

Aber das hast du ja auch schon gemerkt. Datentypen haben halt immer Vorgaben. Du kannst auch keine beliebigezahl in ein integer schreiben.

Wichtig ist auch, bei Vergleich von Floats aufzupassen: Niemals den == oder != Operator verwenden.

Ja, das hab ich schon bemerkt. Das Problem hat man auch bei SQL Abfragen.

welche datenbank arbeitet den bitte mit floats? normal arbeitet man dort mit decimals.