![]() |
Genauigkeit von Datentypen
Guten Mittag, Delphianer,
ich denke ich hab hier etwas gefunden, über das nicht nur ich mir den Kopf zerbreche, aber ich möchte es verstehen, deshalb frag ich euch: Vorarab: Ich wollte einen Münzgeldrechner schreiben (Quellcode ist unten), der einen Betrag, den man eingibt umwandelt in Münzgeld wechselt. Ziel dabei war es, so wenig wie möglich Münzen zu benutzen. Dies war die aufgabenstellung, nun kommt mein dazu passender code
Delphi-Quellcode:
procedure TForm1.edtEingabeChange(Sender: TObject); var EingegebeneZahl: Currency; arGeld: array [0 .. 7] of Currency; i: Integer; zaehler: Integer; begin // Array Füllen arGeld[0] := 2; arGeld[1] := 1; arGeld[2] := 0.50; arGeld[3] := 0.20; arGeld[4] := 0.10; arGeld[5] := 0.05; arGeld[6] := 0.02; arGeld[7] := 0.01; EingegebeneZahl := StrToFloat(edtEingabe.Text); mmoLog.Lines.Add(FloatToStr(EingegebeneZahl)); for i := 0 to 7 do begin zaehler := 0; repeat if EingegebeneZahl < arGeld[i] then begin break; end; mmoLog.Lines.Add('Operation: '+FloatToStr(EingegebeneZahl)+' - '+FloatToStr(arGeld[i])); EingegebeneZahl := EingegebeneZahl - arGeld[i]; mmoLog.Lines.Add(FloatToStr(EingegebeneZahl)); Inc(zaehler); until arGeld[i] > EingegebeneZahl; if arGeld[i] = 2 then lbl2.Caption := IntToStr(zaehler); if arGeld[i] = 1 then lbl1.Caption := IntToStr(zaehler); if arGeld[i] = 0.50 then lbl050.Caption := IntToStr(zaehler); if arGeld[i] = 0.20 then lbl020.Caption := IntToStr(zaehler); if arGeld[i] = 0.10 then lbl010.Caption := IntToStr(zaehler); if arGeld[i] = 0.05 then lbl005.Caption := IntToStr(zaehler); if arGeld[i] = 0.02 then lbl002.Caption := IntToStr(zaehler); if arGeld[i] = 0.01 then lbl001.Caption := IntToStr(zaehler); end; end; Dieser Code funktioniert, soweit ohne fehler!! Ändert man jedoch den Datentyp von currency in double, single o.ä...Funkitioniert das Programm nicht mehr richtig!! (Als kleine veranschaulichung habe ich ein memo eingebaut, welches die aktion mitschreibt, die gerade durchgeführt wird). Es wird nach der Dritten bzw. 4 Berechnung alles ungenau, und es wird nicht mehr weiter berechnet. Ich will wissen warum?!! warum ändert sich der wert von alleine/ wird ungenau... Ich hoffe ein paar von euch können sich einen Reim darauf machen LG Paddy_VII p.s: es geht nicht darum, ob der Code nun effizient ist, oder nicht :?:?:? |
AW: !!Riesenprobelm mit Datentypen!!
Das liegt an der internen Darstellung. Ein Wert 0.5 wird als Double evtl. als 0.5000000128973 gespeichert. Für diese Fälle arbeite mit CompareValue mit einem entsprechenden Delta.
|
AW: !!Riesenprobelm mit Datentypen!!
aber warum genau wird der wert ungenau?? wir haben ihn als double angegeben, klar aber dann müsste doch auch 0,5 0,5000000000000000000000000000 werden und nich irgendwelche wahllosen zahlen hintendranhackseln
|
AW: !!Riesenprobelm mit Datentypen!!
Das hängt damit zusammen, dass auch ein moderner Computer Fließkommazahlen nicht exakt darstellen kann.
Schau mal dort: ![]() |
AW: !!Riesenprobelm mit Datentypen!!
aber dann bedeutet das doch, dass es mit Single double usw. völlig schwachsinnig wäre zu rechnen, weil sie ehh ungenau werden oder?
|
AW: !!Riesenprobelm mit Datentypen!!
Wie genau brauchst Du es denn?
Jeder Datentyp hat eine auf n Stellen garantierte Genauigkeit. Dann muss man schauen, was man braucht und kann dann den entsprechenden Datentyp wählen. "Single" ist für viele, viele Fälle absolut ausreichend. |
AW: !!Riesenprobelm mit Datentypen!!
eben, und ich wollte einfach nur mit max. 2 stellen nach dem Komma rechnen... und dann macht er mir sowas....ist das selbst bei soo wenigen stellen (bei mehr als 30 stellen nach dem komma hätt ich jaa verstanden dass er ungenau wird) relevant?? darf doch eigentlich nicht sein, oder?
|
AW: !!Riesenprobelm mit Datentypen!!
Zitat:
Deine Zahlen sind nur auf die ersten n Stellen korrekt - darauf kannst Du Dich verlassen, auf mehr jedoch auch nicht. Deswegen sollte man Fließkommazahlen auch nicht als Ganzes auf Gleichheit zu irgendeinem anderen Wert prüfen, sondern Funktionen wie "CompareValue" nutzen, die Dir streng genommen nur sagen, ob Wert A "recht dicht" an Wert B ist. |
AW: Genauigkeit von Datentypen
Zitat:
Und aus selbem Grund darf man reelle Typen niemals per Operator (vorallem
Delphi-Quellcode:
) "genau" vergleichen, sondern verwendet z.B. CompareValue, SameValue, IsZero usw.
=
Zitat:
Umrechung: dual <> dezimal |
AW: !!Riesenprobelm mit Datentypen!!
Zitat:
Da üblicherweise die Mantisse binär dargestellt wird, kann man sich noch nicht einmal darauf verlassen, dass kleine ganze Zahlen oder Brüche aus kleinen ganzen Zahlen exakt wiedergegeben werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz