Re: Fließkommazahlen auf Gleichheit prüfen
Ich denke es liegt eher daran das der Compiler optimiert und schon die richtigen Werte einsetzt.
Wenn du die Optimierung abschaltest und das ganze über Zwischenvariablen zuweist hast du eventuell mehr Glück. |
Re: Fließkommazahlen auf Gleichheit prüfen
Die Optimierung hatte cih versuchsweise schon mal abgeschaltet, hat aber auch nichts genützt. Aber wiedem auch sein, ein Beispiel in C tut es auch. Man ist ja flexibel und ist in der Lage sich seine Programmiersprache der Aufgabe entsprechend auszusuchen. ;)
|
Re: Fließkommazahlen auf Gleichheit prüfen
Liste der Anhänge anzeigen (Anzahl: 1)
So, Artikel ist fertig:
Artikel: Prüfe Fließkommazahlen nie auf Gleichheit! Abstract Probleme beim Vergleichen von Fließkommazahlen. Es ist ein beliebter Anfängerfehler, auch wenn ihn hin und wieder auch mal Programmierer machen, die es wissen sollten, weil sie eigentlich über das nötige Hintergrundwissen verfügen (sollten). Und zwar der Vergleich von Fließkommazahlen auf Gleichheit. Was ist daran so gefährlich und warum funktioniert es eben nicht immer? Link: Prüfe Fließkommazahlen nie auf Gleichheit! Und im Anhang das endgültige PFD. |
Re: Fließkommazahlen auf Gleichheit prüfen
Luckie: So ist es eindrucksvoller, da der oft verwendete Vergleich mit 0 schon hier in die Hose geht.
Delphi-Quellcode:
Der Grund ist klar: 0.1 lässt sich mit Floating Point nun mal nicht 100% genau darstellen, ergo ist 0.1f <> -(-0.1)f. Folgerichtig funktioniert aber das hier (weil typisierte Konstanten mit Variablen gleichzusetzen sind):
Var
a,b : Double; begin a := 0.1; b := a - 0.1; if b=0 then ShowMessage('gleich') else ShowMessage ('ungleich'); end;
Delphi-Quellcode:
Aber das hier wiederum nicht :mrgreen:
Const
C : Double = 0.1; Var a,b : Double; begin a := C; b := a - C; if b=0 then ShowMessage('gleich') else ShowMessage ('ungleich'); end;
Delphi-Quellcode:
Weil Konstanten per definitionem nur Platzhalter sind.
Const
C = 0.1; Var a,b : Double; begin a := C; b := a - C; if b=0 then ShowMessage('gleich') else ShowMessage ('ungleich'); end; Fazit: Man kann sich einfach nicht darauf verlassen, das "wo 0 draufsteht auch 0 drin ist". [edit=sakura] BB-Code aktiviert. Mfg, sakura[/edit] [edit] C in den Code eingefügt, danke Sir Thornberry[/edit] |
Re: Fließkommazahlen auf Gleichheit prüfen
wo ist jetzt der unterschied? C wird in beiden Fällen definiert aber nirgends verwendet :gruebel:
|
Re: Fließkommazahlen auf Gleichheit prüfen
:oops: und deswegen auch:
Delphi-Quellcode:
While Time < StrToTime ('09:30') Do
Alzaimar.CanPostImForum := False |
Re: Fließkommazahlen auf Gleichheit prüfen
Hallo Luckie,
ich habe gerade Deinen Artikel gelesen und mir fehlt die Erwähnung des Typs Currency, den benutze ich immer um entsprechende Vergleichsfehler auszuschließen. Grüße Frank |
Re: Fließkommazahlen auf Gleichheit prüfen
Currency hat 4 feste Nachkommastellen. Es handelt sich eigentlich um einen 64bit Integer Wert, also um (z.B.) 10000stel Cent.
Mit 4 Nachkommastellen kommt man aber auch nicht weit. Die richtige Vorgehensweise beim Rechnen mit reelen Zahlen ist entweder die Verwendung von Schutzstellen, oder die Verwendung von BCD-Datentypen. Diese sind aber nicht Bestandteil von Delphi. |
Re: Fließkommazahlen auf Gleichheit prüfen
alzaimar:
Zitat:
Grüße Frank |
Re: Fließkommazahlen auf Gleichheit prüfen
Zitat:
Eine Anwendung von uns berechnet Materialmengen, und da reicht Single z.B. schon gar nicht mehr aus. Die Berechnungen gehen über viele Iterationen und gerade hier potzenzieren sich Rundungsfehler. Wir arbeiten mit Double (das ist dann knapp ausreichend) und zeigen dann maximal 4 Nachkommastellen an. Gerade Iterationen benötigen verdammt viele Schutzstellen. Die Anwendung (und auch die Zahlen) ist übrigens irdisch :zwinker: . Eigentlich benötigen fast alle mathematischen Anwendungen, die sich nicht nur aufs Addieren beschränken, eine höhere Genauigkeit (Anzahl der Stellen), als sie Currency bietet. Dafür ist Currency eben 100% genau. Bei Addition und Subtraktion. Und da sind 0.1 Euro - 0.1 Euro garantiert = 0,0000! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz