Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Zahlenvergleich vom Typ Real (https://www.delphipraxis.net/194796-zahlenvergleich-vom-typ-real.html)

Sidi61 7. Jan 2018 19:43

Zahlenvergleich vom Typ Real
 
Hallo zusammen,

bin heute auf ein Problem gestoßen welches ich mir nicht erklären kann.
Ganz banale Sache - in einem Eingabeformular für ein Kassenbuch soll eine Rechnung erfasst werden. Eingangs wird der Gesamtbetrag eingegeben dann stehen 4 Editfelder für die Eingabe von Einzelbeträgen mit Zuweisung verschiedener Buchungskonten zur Verfügung.

Konkreter Fall (komischer Weise nur bei dieser Zahlenkombination)
Rechnungsbetrag : 43,60
Einzelbetrag1 : 20,95
Einzelbetrag2 : 22,65

Um Eingabefehler zu vermeiden soll die Summe der Einzelbeträge mit dem Gesamtbetrag verglichen werden

var GesBetrag, Summe : Real;

GesBetrag := StrToFloat(Edit.Rechbetrag.text);
Summe := StrToFloat(Edit.Einzelbetrag1.text) + StrToFloat(Edit.Einzelbetrag2.text);

Bei der Prüfung
if GesBetrag <> Summe then ShowMessage('Summendifferenz Rechnungsbetrag: '+FloatToStr(GesBetrag)+' zu Summe Einzel: '+FloatToStr(Summe));

wird ein Fehler angezeigt: Summendifferenz Rechnungsbetrag: 43,6 zu Summe Einzel: 43,6

Das Programm nimmt an dass der GesBetrag größer als die Summe ist. Komischer Weise nur bei dieser Zahlenkombination.

Habe mir jetzt wie folgt geholfen:
if (GesBetrag <> Summe) and (FloatToStr(GesBetrag)<>FloatToStr(Summe)) then

So funktioniert es, das kann aber nicht die Lösung sein :wall:
Hat jemand eine Idee??

Ist kein Scherz!

Zacherl 7. Jan 2018 19:48

AW: Zahlenvergleich vom Typ Real
 
Das nennt sich Gleitkommaungenauigkeit bzw. Rundungsfehler. Du solltest Floats am besten immer mit einer Epsilon-Schranke vergleichen, also z.b.
Delphi-Quellcode:
if (A + B < Epsilon)
, wobei Epsilon einfach eine enorm kleine Zahl sein sollte.

Sidi61 7. Jan 2018 19:57

AW: Zahlenvergleich vom Typ Real
 
verstehe ich jetzt nicht :?:

Rundungsfehler bei Division ja, aber bei Addition??

Darlo 7. Jan 2018 20:17

AW: Zahlenvergleich vom Typ Real
 
Doch das kommt leider vor, ich hatte mal ein einfaches Beispiel, finde ich aber nicht, da kam beim Typen real bei 3x4 oder sowas 11,99 raus. Extended als Type wäre quick and dirty.

Uwe Raabe 7. Jan 2018 20:26

AW: Zahlenvergleich vom Typ Real
 
Die Unit System.Math bietet dafür die Funktion
Delphi-Quellcode:
SameValue
.

p80286 8. Jan 2018 08:41

AW: Zahlenvergleich vom Typ Real
 
Du solltest den Typ Currency verwenden. Die Fließkommatypen Sind meist nur Näherungswerte (die Mathematik dahinter können Dir andere besser erklären). D.H es kann sein, daß Du 12.5 erwartest aber 12,4999999 oder 12,50001 erhältst. Wenn du die Werte mit einer Nachkommastelle darstellst sehen sie gleich aus sind es aber nicht.

Gruß
K-H

P.S.

Zitat:

Zitat von Sidi61 (Beitrag 1390440)
verstehe ich jetzt nicht :?:

Rundungsfehler bei Division ja, aber bei Addition??

Fließkommazahlen sind Berechnungen.

jus 8. Jan 2018 10:11

AW: Zahlenvergleich vom Typ Real
 
Oder du nimmst gleich Ganzzahltyp Int64 oder so, falls dein Zahlenbereich es zu läßt. Ich hatte vor einigen Jahren mal ein Projekt gehabt, wo ich die Gesamtsumme von den gekauften Aktien(mit 4-stellige Kommazahlen) ausrechnen mußte, also eigentlich eine simple Aufgabe und bin auch auf das Problem gestossen, dass die Gleitkommadarstellung bei einigen Zahlen nicht genau arbeiten, wenn man exakt vergleicht. Habe einfach alles mit 10000 multipliziert, da es sich bei mir um 4-stellige Kommazahlen gehandelt haben, und den Vergleich mit Int64 gemacht.

lg,
jus

himitsu 8. Jan 2018 10:17

AW: Zahlenvergleich vom Typ Real
 
Zitat:

Zitat von Sidi61 (Beitrag 1390440)
verstehe ich jetzt nicht :?:

Rundungsfehler bei Division ja, aber bei Addition??

Weil Fließkommatypen eben per se bereits aus Multiplikationen/Divisionen bestehen.

http://docwiki.embarcadero.com/RADSt...)#Reelle_Typen


Zitat:

Zitat von jus (Beitrag 1390463)
Oder du nimmst gleich Ganzzahltyp Int64 oder so, ...

Rate mal was ein Currency ist.
Das ist ein Int64, wo die letzten 4 Dezimalstellen als Nachkomma genutzt werden, also /10000 .

Wenn du das selber mit einem Int64 machst, mußt du z.B. bei Multiplikationen und Divisionen aufpassen, dass danach die Nachkommastellen stimmen. Ebenso mußt du bei Multiplikation mit Überläufen aufpassen.

jus 8. Jan 2018 10:42

AW: Zahlenvergleich vom Typ Real
 
Zitat:

Zitat von himitsu (Beitrag 1390464)
...
Zitat:

Zitat von jus (Beitrag 1390463)
Oder du nimmst gleich Ganzzahltyp Int64 oder so, ...

Rate mal was ein Currency ist.
Das ist ein Int64, wo die letzten 4 Dezimalstellen als Nachkomma genutzt werden, also /10000 .

Wenn du das selber mit einem Int64 machst, mußt du z.B. bei Multiplikationen und Divisionen aufpassen, dass danach die Nachkommastellen stimmen. Ebenso mußt du bei Multiplikation mit Überläufen aufpassen.

Ok, wenn Currency es genauso macht, ist es ja gut, muß ich gestehen, hatte ich nicht gewußt. :duck: Ich hatte damals nur Multiplikationen Kommazahl mit Ganzzahl gebraucht. Mir ist es damals auch nur deswegen aufgefallen, weil mein Algorithmus nur bei bestimmten Zahlen abgestürzt ist. :oops:

lg,
jus


Alle Zeitangaben in WEZ +1. Es ist jetzt 08: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