Warum kann ich keine Floats via oder Vergleichen?
-
Hallo,
warum geht dieser Code nicht wenn ich 0,1 oder 0,2 eingebe? Mit 0,5 gehts ... aber warum?
float test = StrToFloat(Edit1->Text); if (test == 0.10 || test == 0.50 || test == 0.20) { ShowMessage("geht"); }else{ ShowMessage("geht nicht"); }
-
Hallo!
Fliesskommazahlen auf Gleichheit zu vergleichen ist immer schwer und beinahe unmöglich wegen der internen Darstellung der Floats.
Weil du nur eine definierte Anzahl bits zur Verfügung hast kannst du Fliesskommazahlen nicht ganz genau festlegen - d.h. es gibt IMMER Rundungsfehler.
Dir bleiben 2 Möglichkeiten:
Auf ints/long abbilden (z.B. int i = (floatzahl*100) )
oder sowas ekliges konstruieren:float epsilon = 0.001; (kleine Zahl) if( (abs(test-prüfzahl)) < epsilon ) { // bla } {
Ciao,
Harry
-
Hallo,
Das liegt daran, dass Gleitkommazahlen nicht exakt gespeichert werden können so das irgendwo in den hinteren Kommastellen Unterschiede zwischen deinen Zahlen auftreten können.
Zum Vergleich mußt du eine spezielle Funktion verwenden, wo du die Genauigkeit mit angeben kannst. Wie z.Bsp. hier
http://www.c-plusplus.net/forum/viewtopic-var-t-is-221104-and-highlight-is-double+vergleichen.html
Zur Erklärung siehe z.Bsp.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-204392.html
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1421900.html
-
Ich habe einfach anstatt Float Double genommen und schon gehts.
Danke
-
FloatBoy schrieb:
Ich habe einfach anstatt Float Double genommen und schon gehts.
Das verlagert das Problem aber nur auf andere nicht abbildbare Werte. Am grundsätzlichen Problem ändert das nichts.
-
FloatBoy schrieb:
Ich habe einfach anstatt Float Double genommen und schon gehts.
Wie auch schon von Joe_M. angedeutet: Nein.
Alle Vergleiche von Gleitkommazahlen, unabhängig ob nun float, double oder was auch immer, sind niemals genau. Grundsätzlich läuft es in so einem Fall immer auf einen Deltavergleich hinaus, bei dem das Delta abhängig von der Aufgabenstellung gewählt wird.
Vereinfachte Betrachtung:
Fließkommazahlen bassieren wie integrale Datentypen auf der 2er-Potenz.
7 Wäre also das gesetzte Bit für 1 und 2 und 4. Soweit noch gut, nun kommt der Nachkommaanteil hinzu: 0.5, 0.25, 0.125... Jetzt Stell mal 0.3 so dar, das es wirklich verglichen werden kann (inkl. Rundungsfehlern).Schau dir bitte die Lösung von harryjon35 an, die deutet an, wie man es üblicherweise macht. Wenn du mit sowas nicht arbeiten willst, musst du mit Festkommazahlen arbeiten (Wozu es auch Bibliotheken gibt).