Divisionsfehler Bei Float?
Divisionsfehler Bei Float?
Liebes Lazarusforum,
kann es sein, dass Freepascal bei der Division einen winzigen Rundungsfehler bei Float-Typen drin hat? Wenn I eine Float-Variable ist und ich diese dividiere durch 10 kommt 0,399999999 raus und nicht 0,4. Wie kann man das beheben?
Viele Grüße
Karkov
kann es sein, dass Freepascal bei der Division einen winzigen Rundungsfehler bei Float-Typen drin hat? Wenn I eine Float-Variable ist und ich diese dividiere durch 10 kommt 0,399999999 raus und nicht 0,4. Wie kann man das beheben?
Viele Grüße
Karkov
Re: Divisionsfehler Bei Float?
Das kann ich nicht reproduzieren. Wie kommst du auf dieses Resultat?
FPC 2.4.2 i386-linux
FPC 2.4.2 i386-linux
Re: Divisionsfehler Bei Float?
ich hab den Fehler bei fpc-2.4.2-win32
-
- Beiträge: 134
- Registriert: So 30. Nov 2008, 21:53
Re: Divisionsfehler Bei Float?
Der "Fehler" läßt sich nicht beheben (jedenfalls nicht ohne Dezimalarithmethik). Die Werte 0.4= 4/10 oder 0.=1/10 lassen sich in halt Binärarithmetik nicht genau darstellen. Der Wert ist immer der nächstgelegen Floatwert. Deine Angabe läßt vermuten, daß Du mit 32-Bit-Floats rechnest. Allerdings erhalte ich für float=single eine Ausgabe von 4.000000060E-01. Die Rundungseinheit für single ist ca 1.2E-7, der Fehler ist also ein halbe Einheit in der letzten Stelle, besser geht's in der Regel nicht.
-
- Beiträge: 512
- Registriert: Mo 25. Aug 2008, 18:17
- OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
- CPU-Target: x86
- Wohnort: Chemnitz
Re: Divisionsfehler Bei Float?
Das ist kein Fehler, sondern einfach der Preis von Gleitkommarechnung. Das unterscheidet sich auch von CPU zu CPU bzw. der jeweiligen Softwareimplementierung.
Siehe auch: http://en.wikipedia.org/wiki/Floating_p ... y_problems" onclick="window.open(this.href);return false;
Siehe auch: http://en.wikipedia.org/wiki/Floating_p ... y_problems" onclick="window.open(this.href);return false;
-
- Beiträge: 657
- Registriert: Sa 9. Jan 2010, 17:32
- OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
- CPU-Target: 64Bit
Re: Divisionsfehler Bei Float?
Kleiner Tipp: gib die Zahlen niemals in voller Präzision aus, sondern runde auf sinnvoll viele Stellen, dann kommt auch wieder das "korrekte" 0.4 heraus.
Re: Divisionsfehler Bei Float?
Hallo Carli,carli hat geschrieben:Kleiner Tipp: gib die Zahlen niemals in voller Präzision aus, sondern runde auf sinnvoll viele Stellen, dann kommt auch wieder das "korrekte" 0.4 heraus.
mein Problem ist ja gerade, dass es bei einem Schritt auftritt, den ich beim Runden auch nicht vermeiden kann.
Ich will eine 4 auslesen, muss sie aber intern als 0,4 behandeln:
tb:=strtofloat(cbtb.text)/10;
da bringt es auch nix, die Sache mit einem rundungsbefehl zu veruschen unter kontrolle zu bekommen, da ich ja nach dem rundungsbefehl sowieso wieder durch 10 rechnen muss..
tb:=Round(strtofloat(cbtb.text))/10;
Der Fehler bleibt der selbe. Ich bekomme 0,400000002 und nicht 0,4.
Achja und ich nutze FPC-2.4.2 für i386..
Mich würde die Abweichung ja nicht weiter stören, aber ich will den Wert dann mit einer Datenbank abgleichen und 0,4 ist nun mal nicht gleich 0,400000002 und ein "etwa" gibt es ja bekanntlich nicht.
-
- Beiträge: 512
- Registriert: Mo 25. Aug 2008, 18:17
- OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
- CPU-Target: x86
- Wohnort: Chemnitz
Re: Divisionsfehler Bei Float?
Zwei Möglichkeiten:
- Du bleibst bei Float und vergleichst eben mit einer Toleranz. (uses math; ... SameValue(wert1, wert2, 0.0000001))
- Du nimmst in der DB und in deiner Anwendung Integer statt Float und speicherst den entsprechend multiplizierten Wert. So wird das nicht selten im Bankenwesen gemacht. 10 Euro wären dann halt 10000. 50,25 Euro entsprechend 50250. Damit sind Rundungsfehler relativ gut kontrollierbar und die Werte aber immer vergleichbar.
-
- Beiträge: 292
- Registriert: Sa 5. Feb 2011, 20:38
- OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
- CPU-Target: 32Bit
- Wohnort: Wien
Re: Divisionsfehler Bei Float?
Sicher gibt's das:karkov hat geschrieben:Mich würde die Abweichung ja nicht weiter stören, aber ich will den Wert dann mit einer Datenbank abgleichen und 0,4 ist nun mal nicht gleich 0,400000002 und ein "etwa" gibt es ja bekanntlich nicht.
Code: Alles auswählen
// a - Sollwert
// b - Istwert
// c - Maximale Ungenauigkeit
Etwagleich := ( Abs(a - b) < c )
Nachtrag: Waehrend ich an diesem Post gebastelt habe, wurde eben diese Funktion schon gepostet

Re: Divisionsfehler Bei Float?
Danke für die Tipps, damit geht es jetzt einwandfrei!!! 
