Divisionsfehler Bei Float?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
karkov
Beiträge: 69
Registriert: Di 27. Okt 2009, 17:52

Divisionsfehler Bei Float?

Beitrag von karkov »

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

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Divisionsfehler Bei Float?

Beitrag von theo »

Das kann ich nicht reproduzieren. Wie kommst du auf dieses Resultat?
FPC 2.4.2 i386-linux

karkov
Beiträge: 69
Registriert: Di 27. Okt 2009, 17:52

Re: Divisionsfehler Bei Float?

Beitrag von karkov »

ich hab den Fehler bei fpc-2.4.2-win32

indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Divisionsfehler Bei Float?

Beitrag von indianer-frank »

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.

Hitman
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?

Beitrag von Hitman »

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;

carli
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?

Beitrag von carli »

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.

karkov
Beiträge: 69
Registriert: Di 27. Okt 2009, 17:52

Re: Divisionsfehler Bei Float?

Beitrag von karkov »

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.
Hallo Carli,

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.

Hitman
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?

Beitrag von Hitman »

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.

Eclipticon
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?

Beitrag von Eclipticon »

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.
Sicher gibt's das:

Code: Alles auswählen

// a - Sollwert
// b - Istwert
// c - Maximale Ungenauigkeit
 
Etwagleich :=  ( Abs(a - b) < c )
Und moeglicherweise existiert ohnehin eine Funktion hierfuer, die mir gerade nicht einfaellt ... oder du machst eine draus!

Nachtrag: Waehrend ich an diesem Post gebastelt habe, wurde eben diese Funktion schon gepostet ;-)

karkov
Beiträge: 69
Registriert: Di 27. Okt 2009, 17:52

Re: Divisionsfehler Bei Float?

Beitrag von karkov »

Danke für die Tipps, damit geht es jetzt einwandfrei!!! :-)

Antworten