Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Currency oder Double (https://www.delphipraxis.net/184342-currency-oder-double.html)

bernau 19. Mär 2015 09:29

Currency oder Double
 
Ich weis, für Geldbeträge sollte man den Type Currency verwenden. Bei mir ist es allerdings so, daß ich fast überall double verwende. Sei es aus Unwissenheit, weil ich vor 20 Jahren gar nicht wusste, daß es Curreny gibt und ich mir dadurch noch keine Gedanken über diesen Type machte. Sei es aus Faulheit, weil ich später wusste, daß es Currency gibt, aber nicht daran gedacht habe. Sei es aus dem Kölschen Grund "et hät noch immer joot jejange".

Bisher hatte ich in meiner Laufbahn noch keinen wirklichen bemerkbaren Fehler entdeckt und kein Kunde sagte, daß meine Software falsch rechnet.

Wie haltet Ihr es mit Geldbeträgen. Nehmt Ihr Currency oder Double. Seid ehrlich. ;-)

recall 19. Mär 2015 09:33

AW: Currency oder Double
 
Weder noch, ich rechne intern immer in cents, und daher mit LongInts.
Nur beim Anzeigen gebe ich Euros (oder was auch immer) aus.

himitsu 19. Mär 2015 09:35

AW: Currency oder Double
 
Im Programm wird hier auch überall Double genutzt, aber die Berechnungen laufen fast ausschließlich in der DB ab und dort wird mit NUMERIC (also BCD) gearbeitet/gespeichert.

Das Problem sind die Rundungsprobleme, wie du in dem anderen Thread grade gut nachlesen kannst.

Lemmy 19. Mär 2015 09:54

AW: Currency oder Double
 
Hi,

Überall dort wo die 4 Nachkommastellen und der Wertebereich ausreicht mit Currency (unabhängig ob das Währungsbeträge sind oder nicht). Nur dort wo das nicht ausreicht mit Double oder wenn ich genau sein muss dann mit einer entsprechend kleineren Einheit mit Ganzzahlen.

Ich habe erst letztes Jahr unter heftigem Kampf eine Anwendung zur Rechnungserstellung von Float/Double auf Currency umgebaut. Eine neue Anforderung war die Rechnungsdaten als XML dem Auftraggeber zu übergeben und da gab es einfach zwischen Rechnung auf Papier und der XML ständig Differenzen. Bis dahin wurden diese Differenzen schlicht nie festgestellt - und der Auftraggeber unterstellte mir ständig fehlerhafte Berechnungen-. Erst nach vollständigem Austausch Float - Currency war das Thema durch....

bernau 19. Mär 2015 10:22

AW: Currency oder Double
 
Zitat:

Zitat von himitsu (Beitrag 1294009)
Das Problem sind die Rundungsprobleme, wie du in dem anderen Thread grade gut nachlesen kannst.

Der Thread war ja auch Grund für diesen Thread.

Aber ich hatte noch nie wirklich Rundungsprobleme. Rundungsprobleme bei Double habe ich doch nur, wenn ich mehr als die 15 Siginifikanten stellen verwende. Also im Milliarden-Bereich. Arbeite ich mit Zahlen im Millionen-gereich, dann entsteht der Rundungsfehler doch erst ab der 4 Stelle hinter dem Komma. Der ist doch vernachlässigbar.

Darlo 19. Mär 2015 10:30

AW: Currency oder Double
 
Hi,

ich hatte mal einen Rundungsfehler mit real und double, bin dann extended gegangen. Heute weiß ich auch das es currency gibt, meine Finger tippen aber ständig double...

himitsu 19. Mär 2015 10:52

AW: Currency oder Double
 
Zitat:

Zitat von Darlo (Beitrag 1294026)
meine Finger tippen aber ständig double...

Delphi-Quellcode:
type Double = Currency;
ganz oben in deine Units. :stupid:

Bjoerk 19. Mär 2015 10:53

AW: Currency oder Double
 
Ich verwende double und zur Anzeige Round(Value * 100) / 100. Dabei muß man sicherstellen daß 100 * Value im int64 Bereich liegt.

Darlo 19. Mär 2015 10:56

AW: Currency oder Double
 
Zitat:

Zitat von Bjoerk (Beitrag 1294035)
Ich verwende double und zur Anzeige Round(Value * 100) / 100. Dabei muß man sicherstellen daß 100 * Value im int64 Bereich liegt.

Ich verwende anstatt round
Delphi-Quellcode:
function RoundX(const Value:Extended; const nk:Integer):Extended;
var
   multi: Extended;
begin
   multi := IntPower(10, nk);
   Result := RoundUp(Value*multi) / multi;
end;

Darlo 19. Mär 2015 10:57

AW: Currency oder Double
 
Zitat:

Zitat von himitsu (Beitrag 1294033)
Zitat:

Zitat von Darlo (Beitrag 1294026)
meine Finger tippen aber ständig double...

Delphi-Quellcode:
type Double = Currency;
ganz oben in deine Units. :stupid:

:thumb:

mm1256 19. Mär 2015 11:13

AW: Currency oder Double
 
Zitat:

Zitat von bernau (Beitrag 1294006)
Bisher hatte ich in meiner Laufbahn noch keinen wirklichen bemerkbaren Fehler entdeckt und kein Kunde sagte, daß meine Software falsch rechnet.

Wenn eine SW falsch rechnet, dann war bzw. ist die Ursache ja meistens der Programmierer. Das Problem sitzt ja bekanntlich meistens vor dem PC :cyclops:
Darum denke ich, dass es - bei richtiger Anwendung - keine Falschberechnungsunterschiede (blödes Wort) zwischen Currency und Double gibt.

Zitat:

Zitat von bernau (Beitrag 1294006)
Wie haltet Ihr es mit Geldbeträgen. Nehmt Ihr Currency oder Double. Seid ehrlich. ;-)

Ich nehme generell Double, weil ansonsten manchmal Abweichungen entstehen können. Speziell bei Berechnungsketten wie z.B. bei Artikelpreisen: Listenpreis abzüglich Händlerrabatt, zuzüglich Rohstoffzuschlag, zuzüglich Aufschlag, abzüglich Mengenrabatt, zuzüglich Märchensteuer....

Da speichere ich in den Stammdaten alle Nachkommastellen die der Double hergibt. Runden tu ich dann erst bei der Fakturierung.

Blup 19. Mär 2015 12:00

AW: Currency oder Double
 
Abrechnung in der Datenbank mit Numeric() also Festkomma, deshalb keine Probleme in dieser Beziehung.
Im Programm selbst wird Double verwendet, aber dort wird eigentlich nur addiert oder mit Ganzzahl multipliziert.
Die Ausgabe wird natürlich gerundet. Probleme sind nicht bekannt.

Das einzig bekannte Rundungsproblem hat nur indirekt mit dem Datentyp zu tun.
Wir erstellen in der Regel Ausgangsrechnungen abei denen die Einzelpositionen Brutto ausgewiesen werden.
Die Mehrwertsteuer wird auf den Gesamtbetrag je Mehrwertsteuersatz berechnet.

Brutto MwSt. Steuer Netto
10,00 19% 1,60 8,40

Da sich dieser Betrag aber aus unterschiedlichen Leistungen zusammensetzt,
sollen die Teilbeträge in die Buchhaltung getrennt für verschieden Erlöskonten übergeben werden.

Brutto MwSt. Steuer Netto
06,60 19% 1,05 5,55 Erlöskonto1
03,40 19% 0,54 2,86 Erlöskonto2

Es gibt verschiedene Möglichkeiten das Problem zu umgehen (separate Steuerbuchung, Zwischenkonto), damit zumindest die Steuersumme stimmt.
Diese sind nicht bei jeder Buchhaltungssoftware auf die gleich Weise anwendbar.
Das Problem verschiebt sich dadurch nur, von welchem Erlöskonto zieht man jetzt den Steuer-Cent ab?

mm1256 19. Mär 2015 12:13

AW: Currency oder Double
 
Zitat:

Zitat von Blup (Beitrag 1294053)
Das Problem verschiebt sich dadurch nur, von welchem Erlöskonto zieht man jetzt den Steuer-Cent ab?

Lösbar ist das Problem ja nicht. Also schlucke ich die kleinste Kröte und nehme immer das (Erlös-)Konto mit dem höchsten Betrag, weil dadurch die Fibu insgesamt am wenigsten verfälscht wird. Der Anwender kann noch einstellen, ob und wie er informiert werden möchte. Im Logfile steht es aber generell.

p80286 19. Mär 2015 13:52

AW: Currency oder Double
 
!currency!
Ohne Currency gab es im Zusammenspiel von DB, Frontend und erstellten Briefen (Word mit ein paar Macros) immer wieder Abweichungen im Cent-Bereich, die nervig bis peinlich waren.
Jetzt herrscht Ruhe!

Gruß
K-H

himitsu 19. Mär 2015 14:26

AW: Currency oder Double
 
Da viele Textausgabefunktionen (Float->String) eher abrunden/abschneiden, müsste man beim Double entweder "runden" oder vor Anzeige 'nen 1/100stel oder 1/1000stel traufrechnen, damit meistens richtig "abgerundet" wird.

mm1256 19. Mär 2015 14:36

AW: Currency oder Double
 
Zitat:

Zitat von p80286 (Beitrag 1294066)
!currency!
Ohne Currency gab es im Zusammenspiel von DB, Frontend und erstellten Briefen (Word mit ein paar Macros) immer wieder Abweichungen im Cent-Bereich, die nervig bis peinlich waren.
Jetzt herrscht Ruhe!

Gruß
K-H

Kann es sein, dass diese Abweichungen auch was mit der Datenbank zu tun haben? Ich verwende NexusDB - die ja bekanntlich in Delphi programmiert ist - und hatte diesbezüglich noch keine Probleme.

Dejan Vu 19. Mär 2015 15:24

AW: Currency oder Double
 
Also floating point ist floating point, egal wer mit wem und wo das programmiert wurde. Wenn Nexus-DB hier kein FP nimmt, sondern BCD, dann wäre das ja mal was, wobei 'Numeric(x,y)' zumindest in SQL-Server auch eine BCD ist.

FP und Währungen sind eine Qual. Wir haben ein Bankensystem, bei dem die Honks, die das programmiert haben, alle Währungen in der DB als 'float' abgebildet haben (SQL-Server) und nun müssen sie in jeder 2.Zeile die Werte krampfhaft runden. Und selbst dann kann ich von einem Konto, auf dem noch 9.99 Euro drauf sind, nicht immer 9.99 Euro abheben, weil der Dispo auf 0.00 ist und -0.0000000000000000123 eben weniger als 0.00 sind. :wall:

Zu den Argumenten: "Bei mir ist noch nie was passiert" fällt mir immer nur der Autofahrer ein, der ohne Sicherheitsgurt fährt, und das gleiche sagt.

Wegen interner Berechnungen von Zinsen etc. verwenden wir BCD, da ist Currency leider nicht genau genug. Aber in er DB würde ich nur noch 'money' verwenden. In der Darstellungsschicht würde ich allerdings auf Currency setzen, weil das irgendwie dem nahe kommt, was man darstellen will.

Vor Jahren haben wir mal eine Logistik- und Abrechnungssoftware mit Double gebaut, das war ähnlich krank. Da hatten wir zwar keine Probleme in der DB, aber dafür bei der Rechnungslegung. Was da für Rundungsprobleme entstanden sind, verstehe ich bis heute nicht, aber sie waren da.

Lemmy 19. Mär 2015 15:36

AW: Currency oder Double
 
Zitat:

Zitat von Dejan Vu (Beitrag 1294081)
FP und Währungen sind eine Qual. Wir haben ein Bankensystem, bei dem die Honks, die das programmiert haben, alle Währungen in der DB als 'float' abgebildet haben (SQL-Server) und nun müssen sie in jeder 2.Zeile die Werte krampfhaft runden. Und selbst dann kann ich von einem Konto, auf dem noch 9.99 Euro drauf sind, nicht immer 9.99 Euro abheben, weil der Dispo auf 0.00 ist und -0.0000000000000000123 eben weniger als 0.00 sind. :wall:

Drollig wird es dann, wenn die Programmierer angewackelt kommen und fragen, warum da -0.0000000000000000123 raus kommt - weil sie runden ja vorher (einen Double auf einen Double)...

Zitat:

Zitat von Dejan Vu (Beitrag 1294081)
Zu den Argumenten: "Bei mir ist noch nie was passiert" fällt mir immer nur der Autofahrer ein, der ohne Sicherheitsgurt fährt, und das gleiche sagt.

das hinkt... Das Problem ist doch: Es passiert immer wieder, nur fällt es nicht auf. Wie bei der Software die ich in meinem letzten Post beschrieben habe: Über Jahrzehnte wird da mit Double gerechent - die Unterschiede (und Rechenfehler) sind erst dann aufgefallen, als ich die gleichen Daten in eine XML schreiben musste - da aber halt als Cent-Betrag ohne Nachkommastellen und auf einmal hat sich Papierrechnung und XML unterschieden....

Dejan Vu 19. Mär 2015 16:43

AW: Currency oder Double
 
[QUOTE=Lemmy;1294082das hinkt... [/QUOTE] Das Wesen eines guten Vergleiches ;-()
Du kannst auch mal ohne Gurt auf deinen Vordermann stupseln. Aber klar. Im Grunde genommen ist die Einstellung, ohne Gurt ginge es auch, etwas fataler in der Auswirkung als 'Double als Währung'.

Grad gestern hat der 'Lead Developer' hier gemeint, wir sollten doch bitte auch in neuen Funktionen mit 'Float' und 'Double' arbeiten, sonst würde man ja ganz konfus.. :thumb:
:wall:

bernau 19. Mär 2015 17:28

AW: Currency oder Double
 
Zitat:

Zitat von Lemmy (Beitrag 1294082)
Drollig wird es dann, wenn die Programmierer angewackelt kommen und fragen, warum da -0.0000000000000000123 raus kommt - weil sie runden ja vorher (einen Double auf einen Double)...

Ja, ein Double ist ein Double. Und wenn ich weis, wie ich mit einem Double umgehen muss, dann passiert mir so etwas nicht.

Das soll jetzt kein Fürsprecher für Double sein. Aber auch mit Currency gibt es bestimmt auch Fallstricke. Man muss ich eben mit dem Zahlentyp auskennen.

Dejan Vu 19. Mär 2015 17:41

AW: Currency oder Double
 
Erstmal richtig: Auskennen muss man sich.

Bei Double wird aus klaren Anweisungen dann leider idiotischer und unverständlicher Code.
Beispiel:
Vorgabe: Abheben darf ich einen Betrag X, wenn der auf dem Konto verbleibende Betrag nicht kleiner als der Dispo ist. Oder einfacher: Die Bedingung lautet 'Betrag - X >= Dispo'. Das möchten wir bitte so im Code umsetzen. Aber was muss ich stattdessen machen? 'Abs(Betrag - X - Dispo) >= Epsilon'! WTF?

bernau 19. Mär 2015 18:10

AW: Currency oder Double
 
Zitat:

Zitat von Dejan Vu (Beitrag 1294109)
Erstmal richtig: Auskennen muss man sich.

Bei Double wird aus klaren Anweisungen dann leider idiotischer und unverständlicher Code.
Beispiel:
Vorgabe: Abheben darf ich einen Betrag X, wenn der auf dem Konto verbleibende Betrag nicht kleiner als der Dispo ist. Oder einfacher: Die Bedingung lautet 'Betrag - X >= Dispo'. Das möchten wir bitte so im Code umsetzen. Aber was muss ich stattdessen machen? 'Abs(Betrag - X - Dispo) >= Epsilon'! WTF?

Dafür kann man sich schöne sprechende Funktionen schreiben

Dejan Vu 19. Mär 2015 19:03

AW: Currency oder Double
 
Zitat:

Zitat von bernau (Beitrag 1294114)
Dafür kann man sich schöne sprechende Funktionen schreiben

Delphi-Quellcode:
If IsLessThan(X-Y,Z) then
ist ja auch viel besser lesbar als
Delphi-Quellcode:
If X-Y<Z then
.. oder war das doch anders herum? :gruebel:

Ach ja, und immer (auf)runden. Und aufpassen. Immer aufpassen. Und hier noch ein Runden und da noch eins.

Also ich nehm lieber den einfachen Weg und nimm kein Double.

BUG 19. Mär 2015 20:30

AW: Currency oder Double
 
Man könnte sein Double (oder was auch immer) auch in einen eigenen Typ (record) packen und dessen Operatoren so definieren wie man es braucht.
Genauso lesbar, aber etwas flexibler :wink:

Dejan Vu 20. Mär 2015 05:13

AW: Currency oder Double
 
Die Operatorenüberladen hatte ich ü-ber-haupt-nicht auf dem Schirm :thumb: Das wäre der geeignete Workarund.

Wobei -zumindest aus meiner Erfahrung her- immernoch die blöden, teilweise unmotivierten Rundungen kommen.

Ich würde Currency für eine Währung nehmen und jede Umrechnung (Steuer, Abschlag, Währung etc.) über eine wohldefinierte Funktion abbilden. Denn diese sind bis auf den Cent definiert und über Unittests abbildbar.

Aber egal. Das Thema ist durch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:31 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 by Thomas Breitkreuz