unleserliche darstellung bei kontostand über 1 million



  • mgaeckler schrieb:

    Warum? Nur mit double kannst Du die Schulden der BRD auf das Cent genau berechnen.

    Mit double kann man gar nix auf den Cent genau berechnen. Probier zB mal:

    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main()
    {
    	double betrag = 0.1;
    
    	for(int i = 0; i < 9; ++i)
    		betrag += 0.1;
    
    	cout << setprecision(20) << fixed << betrag;
    }
    

    und Du wirst sehen, dass double Rundungsfehler aufweist. Wenn man sich nun eine Vielzahl von Addition/Subtraktionsoperationen vorstellt, wo die (Zwischen)ergebnisse möglicherweise noch multipliziert/dividiert werden, dann erkennt man, dass man unter dem Strich erhebliche Abweichungen von den tatsächlichen Ergebnissen erhält.

    Deshalb nochmal:

    SeppJ schrieb:

    double ist ein denkbar schlechter Datentyp um damit gequantelte Größen, wie Geld, zu behandeln.



  • Belli schrieb:

    mgaeckler schrieb:

    Warum? Nur mit double kannst Du die Schulden der BRD auf das Cent genau berechnen.

    Mit double kann man gar nix auf den Cent genau berechnen. Probier zB mal:

    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main()
    {
    	double betrag = 0.1;
    	
    	for(int i = 0; i < 9; ++i)
    		betrag += 0.1;
    		
    	cout << setprecision(20) << fixed << betrag;
    }
    

    und Du wirst sehen, dass double Rundungsfehler aufweist. Wenn man sich nun eine Vielzahl von Addition/Subtraktionsoperationen vorstellt, wo die (Zwischen)ergebnisse möglicherweise noch multipliziert/dividiert werden, dann erkennt man, dass man unter dem Strich erhebliche Abweichungen von den tatsächlichen Ergebnissen erhält.

    Deshalb nochmal:

    SeppJ schrieb:

    double ist ein denkbar schlechter Datentyp um damit gequantelte Größen, wie Geld, zu behandeln.

    Ja, schon recht. Man muß aber nicht päpstlicher als der Papst sein:

    0.1 + 0.1 = 0.200000000000000011

    Da mussen schon einige Rechnungen zusammen kommen, bis sich dieser Fehler in Cent auswirkt.

    Ich sag jetzt einfach mal so: Wenn es um finazmathematische Berechnungen mit einigermassen überschaubaren Beträgen und Zeiträumen geht, kann man ohne Probleme den Typ double benutzen.

    Wer aber auf den Cent genau ausrechnen will, wieviel Zinsen ein Neandertaler heute bezahlen muß, der sich vor 100000 Jahren ein Mamut geliehen hat, der sollte vieleicht was anderes benutzen.

    mfg Martin



  • Ich sag jetzt einfach mal so: Wenn es um finazmathematische Berechnungen mit einigermassen überschaubaren Beträgen und Zeiträumen geht, kann man ohne Probleme den Typ double benutzen.

    Mit dem Argument ist aber auch ein long gross genug. Warum also den fehlerhaften double nehmen?


  • Mod

    mgaeckler schrieb:

    Da mussen schon einige Rechnungen zusammen kommen, bis sich dieser Fehler in Cent auswirkt.

    Ich sag jetzt einfach mal so: Wenn es um finazmathematische Berechnungen mit einigermassen überschaubaren Beträgen und Zeiträumen geht, kann man ohne Probleme den Typ double benutzen.

    Wer aber auf den Cent genau ausrechnen will, wieviel Zinsen ein Neandertaler heute bezahlen muß, der sich vor 100000 Jahren ein Mamut geliehen hat, der sollte vieleicht was anderes benutzen.

    Das ist ein ganz gefährlicher und kurzsichtiger Rat, den du da gibst. Man muss kein Numeriker sein, um einfache Rechenbeispiele zu finden, in denen der relative Fehler explodiert. Eine einfache Subtraktion zweier ähnlicher Werte genügt. Und wenn man das Ergebnis noch multipliziert oder exponenziert, dann wird auch der absolute Fehler groß.



  • Ne, ich habe mir vor (wirklich vielen) Jahren mal eine Anwendung zur Kontoverwaltung geschrieben. Dort habe ich aus Unwissenheit double für die Betragsspeicherung gewählt.

    Da kommen im Jahr sicher keine 1000 Datensätze zusammen. Wenn ich da einfach alle Buchungen addiere - wobei es natürlich jede Menge Buchungen mit negativem Vorzeichen gibt - dann habe ich ab und zu eine Abweichung von 1 Ct. gegenüber dem tatsächlichen Kontostand.
    Wenn ein paar Wochen später weitere Buchungen hinzugekommen sind, gleicht sich das häufig wieder aus.
    Aber: Es ist eine Abweichung spürbar, und zwar ohne dass Multiplikationen/Divisionen zur Anwendung kommen.

    Also für Anwendungen mit etwas ernsthafteren Ambitionen ist das wirklich nicht zu empfehlen.

    Mir selbst ging das nach einer Weile so auf den Wecker, dass ich die Doubles nun vor der Addition nach int konvertiere, addiere, und dann für die Bildschirmdarstellung wieder ein Komma dazwischen fummel.

    Viel problematischer für mich war beim ersten Auftreten, dass ich mir das gar nicht erklären konnte, da mir diese Problematik überhaupt nicht bekannt war, deshalb finde ich es okay, Programmierpadawane so früh wie möglich darauf hinzuweisen und das auch nicht zu verharmlosen.



  • Welcher Datentyp wäre dann eurer Meinung nach der geeignetste?


  • Mod

    freddixx schrieb:

    Welcher Datentyp wäre dann eurer Meinung nach der geeignetste?

    Wenn du es mit Zuckerguss haben möchtest: Schreib dir eine Geldklasse. Das wäre in C++ (oder allgemein der objektorientierten Programmierung) die übliche Herangehensweise.

    Wenn du bloß schnell ein Beispielprogramm zusammenhacken möchtest: Ein ganzzahgliger Datentyp wie int bewahrt dich erst einmal vor dem schlimmsten, denn Geld kommt schließlich auch immer in ganzen Einheiten. Dann rechnest du eben in Cent oder Zehntelcents ansstatt in Euros.



  • Jockelx schrieb:

    Ich sag jetzt einfach mal so: Wenn es um finazmathematische Berechnungen mit einigermassen überschaubaren Beträgen und Zeiträumen geht, kann man ohne Probleme den Typ double benutzen.

    Mit dem Argument ist aber auch ein long gross genug. Warum also den fehlerhaften double nehmen?

    long hat auf 32-Bitsystemen einen Wertebereich von ca +/-2000000000 in Euro sind das gerade mal 20 Milionen. Das erscheint mir dann doch zu wenig auch wenn es für die meisten (eh irgendwelche Spekulationen aufkommen: Auch für mein Unternehmen) ausreicht.

    Man muß einfach sich überlegen, welche Datentypen-/strukturen welche Vor- und Nachteile haben. Für eine Ganzzahlrechnung, wie auch immer die ausschaut, spricht, daß man sich nicht um Rundungsfehler kümmern muß. Dagegen spricht aber, daß diese nicht so flexibel sind. Man muß einmal die Semantik definieren (ist das Cent, zehntel oder gar hundertstel Cent) und diese durch das ganze Programm durchziehen. Was aber ist, wenn der Gesetzgeber plötzlich anfängt, da herum zu spielen, dann kann es einem passieren, daß hier plötzlich alles über den Haufen geworfen werden muß. Der Wartungsaufwand kann dann echt übel werden.

    mfg Martin



  • Belli schrieb:

    Ne, ich habe mir vor (wirklich vielen) Jahren mal eine Anwendung zur Kontoverwaltung geschrieben. Dort habe ich aus Unwissenheit double für die Betragsspeicherung gewählt.

    Da kommen im Jahr sicher keine 1000 Datensätze zusammen. Wenn ich da einfach alle Buchungen addiere - wobei es natürlich jede Menge Buchungen mit negativem Vorzeichen gibt - dann habe ich ab und zu eine Abweichung von 1 Ct. gegenüber dem tatsächlichen Kontostand.
    Wenn ein paar Wochen später weitere Buchungen hinzugekommen sind, gleicht sich das häufig wieder aus.
    Aber: Es ist eine Abweichung spürbar, und zwar ohne dass Multiplikationen/Divisionen zur Anwendung kommen.

    Also für Anwendungen mit etwas ernsthafteren Ambitionen ist das wirklich nicht zu empfehlen.

    Mir selbst ging das nach einer Weile so auf den Wecker, dass ich die Doubles nun vor der Addition nach int konvertiere, addiere, und dann für die Bildschirmdarstellung wieder ein Komma dazwischen fummel.

    Viel problematischer für mich war beim ersten Auftreten, dass ich mir das gar nicht erklären konnte, da mir diese Problematik überhaupt nicht bekannt war, deshalb finde ich es okay, Programmierpadawane so früh wie möglich darauf hinzuweisen und das auch nicht zu verharmlosen.

    Hallo,

    eine solche Erfahrung habe ich bisher nicht gemacht und das wäre echt übel, wenn dem so wäre. Dann müsste ich tatsächlich eine Aussage zurückziehen. Ich kann mir allerdings nicht vorstellen, daß es an dem Datentyp double liegt, werde aber mal versuchen, ob ich ein Testprogramm schreiben kann, mit dem das nachvollzogen werden kann. Bis dahin werde ich allerdings meine Äusserung nicht wiederholen.

    mfg Martin



  • @mgaeckler:
    Deswegen ja eine Geldklasse. Ein simpler Wrapper um einen int64 (reicht für über 90 Billiarden €, also vermutlich zumindest für das nächste halbe Jahrtausend) mit hübscher Ausgaberoutine und ein paar Konvertierungsfunktionen. Also mitsamt Testen in vielleicht 1/2h bis 1h geschrieben. Alternativ in 5min aus dem Netz geladen. Und schon hat man (vorläufig) nie mehr Probleme weder mit Wertebereich noch mit Genauigkeit. Und wenn der Gesetzgeber den Zehntelcent einführt, ändert man eine Klasse und eine Ausgaberoutine. Wer weiß, wie viele Stellen man mit double hätte, an denen manuell auf 2 Nachkommastellen gerundet wird?



  • Überleg nochmal, ob eine Zahl mit 9 Nullen 20 Millionen ist 😉
    Edit: ach sry, du hast die cent wahrscheinlich schon weggestrichen.

    Ich bleib dabei:
    Das reicht oder man muss es eh anständig machen und das macht man sicherlich nicht mit double.



  • SeppJ schrieb:

    Das ist ein ganz gefährlicher und kurzsichtiger Rat, den du da gibst. Man muss kein Numeriker sein, um einfache Rechenbeispiele zu finden, in denen der relative Fehler explodiert. Eine einfache Subtraktion zweier ähnlicher Werte genügt. Und wenn man das Ergebnis noch multipliziert oder exponenziert, dann wird auch der absolute Fehler groß.

    Hallo,

    ich habe während meiner Schul- und Unizeit mich ausführlich mit Fehlerrechnung in der Physik beschäftigen dürfen. Mir ist also schon klar, welche Fehler sich bei welchen Operationen wie auswirken. Ich bin bisher davon ausgegangen, daß die Genauigkeit von double für die meisten Berechnungen im Finanzwesen ausreichend ist.

    Wenn ich mir das Beispiel von Beli anschauen, kommen mir dann aber doch Zweifel. 😞

    mfg Martin



  • Jockelx schrieb:

    Überleg nochmal, ob eine Zahl mit 9 Nullen 20 Millionen ist 😉
    Edit: ach sry, du hast die cent wahrscheinlich schon weggestrichen.

    Korrekt, so ist es.

    Jockelx schrieb:

    Ich bleib dabei:
    Das reicht oder man muss es eh anständig machen und das macht man sicherlich nicht mit double.

    Ich werde mal ein Testprogramm machen. Bin mal gespannt, was dabei rauskommt.

    mfg Martin



  • ipsec schrieb:

    @mgaeckler:
    Deswegen ja eine Geldklasse. Ein simpler Wrapper um einen int64 (reicht für über 90 Billiarden €, also vermutlich zumindest für das nächste halbe Jahrtausend)

    Weltfremd, hihihi.
    http://www.focus.de/finanzen/doenchkolumne/staatsverschuldung-in-sechs-tagen-sind-die-usa-pleite_aid_625738.html

    Wenn man dann noch erlauben will, daß der Programmierer Prozentrechnung tätigen darf (nur ganzahlige Prozente, aber mit kaufmännischer Rundung), also ohneMwst=(mitMwst*200+1)/238, haben wir den Wertebereich schon ums zwanzigfache Überschritten. 😮



  • Billionen != Billiarden



  • freddixx schrieb:

    Billionen != Billiarden

    Ups. Ok, dann haben wir noch 20 oder 30 Jahre.



  • Selbst wenn ist in eben dieser einen Klasse aus dem int64 auch mal schnell ein int128 gemacht. Und das reicht dann laaaange!



  • Ooooch, bloß nicht allzu gut vorbereitet sein. Uns betrifft's ja nicht & manch einem täte ein Überlauf ganz gut. 🙂



  • mgaeckler schrieb:

    Ich bin bisher davon ausgegangen, daß die Genauigkeit von double für die meisten Berechnungen im Finanzwesen ausreichend ist.

    Das ist auch richtig. Zum einen drehen sich die meisten Berechnungen im Finanzwesen nicht um Beträge, sondern um relative Größen (diese sind direkt vergleichbar), und zum anderen ist es für komplexere Berechnungen auch mit Beträgen häufig notwendig, spitzer als Cents zu rechnen. Von Stufenfunktionen lassen sich keine Ableitungen nehmen.

    Sobald man allerdings in die Buchführung kommt, sind Fließkommazahlen denkbar ungeeignet.



  • Danke SeppJ!

    Das ist genau das, was ich brauchte!


Anmelden zum Antworten