Datentypen für Geldbeträge und Ziffernfolgen (Split aus: Vererbung und destruktor)


  • Mod

    Igl schrieb:

    int kreditkartenNr
    double saldo
    int blz

    Nein! Nein! Nein! Geldbeträge sind keine Fließkommazahlen und so ziemlich alle 'Nummern' und 'Zahlen' im Alltag sind keine Zahlen, sondern Ziffernfolgen, egal was der Name sagt.



  • SeppJ schrieb:

    Nein! Nein! Nein! Geldbeträge sind keine Fließkommazahlen und so ziemlich alle 'Nummern' und 'Zahlen' im Alltag sind keine Zahlen, sondern Ziffernfolgen, egal was der Name sagt.

    Diese interessante Aussage sehe ich bereits zum zweiten mal von dir.

    Speicherst du deine Geldbeträge als strings ab?
    Ich würde ja gerne Ganzzahlen verwenden jedoch kommen bei mir Beträge wie 0,05ct vor.



  • DocShoe schrieb:

    @Neugear:
    Dann nimm eine BigInteger Bibliothek und rechne in 0.0001 Cent-Einheiten. Oder noch kleiner, bis es passt.

    Edit:
    Wenn du __int64 benutzt und in 0.001 Cent-Einheiten rechnest kannst du immer noch mit bis zu +/- 9.223.372.036.854€ rechnen.

    Ah Stimmt. Der Datentyp long long würde es auch abdecken oder sollte ich trotzdem eine BigInteger Bibliothek verwenden?



  • NeugierGEAR schrieb:

    Ich würde ja gerne Ganzzahlen verwenden jedoch kommen bei mir Beträge wie 0,05ct vor.

    Wärest du damit einverstanden, nur 99 Cent auf dem Konto zu haben, wenn du 100 mal einen Cent einzahlt? Wenn ja, dann verwende ruhig floats.

    Oder mal angenommen, du bist Multimillionär und hast 16777216€ auf dem Konto. Nun überweise dir jemand einen Euro. Danach hast du immer noch 16777216€ auf dem Konto und der eine Euro ist einfach futsch. Wenn du das ok findest, nimm float.

    Ansonsten rechne in Cent oder in 1/100 Cent (oder wie auch immer die Anforderung ist) und nimm einen groß-genugen Ganzzahltyp.


  • Mod

    Ich hätte auch gerne genau einen Cent auf dem Konto, nicht nur 0.00999999977648258209228515625



  • SeppJ schrieb:

    Ich hätte auch gerne genau einen Cent auf dem Konto, nicht nur 0.00999999977648258209228515625

    ^^Kaufmännisches Runden.



  • Du kannst so viel runden wie du willst, du kommst trotzdem nicht näher an die Darstellung von 0.001. Und, was passiert wenn du eine ungenaue Darstellung von 0.001 (irgendwas wie 0.009987564) mit einer ungenauen Darstellung von 100 multiplizierst?
    Die Repräsentation von Floatingpoint zahlen, ist dafür einfach nicht geeignet.



  • Schlangenmensch schrieb:

    mit einer ungenauen Darstellung von 100 multiplizierst?

    Wo soll die denn herkommen? Ganzzahlen werden exakt dargestellt. Die Grenze nach oben ist bei float 16777216.
    Oder meinst du eine Zahl wie std::nextafter(100.f, 200.f) ?



  • Schlangenmensch schrieb:

    Du kannst so viel runden wie du willst, du kommst trotzdem nicht näher an die Darstellung von 0.001. Und, was passiert wenn du eine ungenaue Darstellung von 0.001 (irgendwas wie 0.009987564) mit einer ungenauen Darstellung von 100 multiplizierst?
    Die Repräsentation von Floatingpoint zahlen, ist dafür einfach nicht geeignet.

    Richtig!

    Ich habe nur auf die plumpe Antwort von SeppJ eine Antwort gegeben. Somit hat er sein Cent.



  • NeugierGEAR schrieb:

    Ah Stimmt. Der Datentyp long long würde es auch abdecken oder sollte ich trotzdem eine BigInteger Bibliothek verwenden?

    Naja kommt drauf an mit welcher Inflation du rechnest.
    Grundsätzlich kann man davon ausgehen dass es den Leuten irgendwann mal zu doof wird. Also wenn ne Semmel mal eine Million kostet oder so. Irgendwann wird dann ne neue Währung ausgegeben.

    Der COM Standard von Microsoft verwendet für Geldbeträge z.B. 64 Bit Fixkomma mit Faktor 10000.
    https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/currency-data-type
    D.h. du kannst 922337 Milliarden darstellen.
    Bei einem Wurstsemmelpreis von einer Million wäre das ein Problem, dann könntest du nichtmal mittlere Firmenkonten verwalten.

    Weniger Kommastellen, also z.B. nur 2 oder 3 statt 4, können aber u.U. auch zu einem Problem werden (bin mir nichtmal sicher ob 4 reicht!).

    SQL Server ist erschreckenderweise genau so eingeschränkt: https://docs.microsoft.com/en-us/sql/t-sql/data-types/money-and-smallmoney-transact-sql
    (Wobei man da auf "numeric" bzw. "decimal" ausweichen kann wenn man einen grösseren Bereich oder mehr Kommastellen braucht...)

    => Wenn du wirklich auf Nummer sicher gehen willst, dann nimm irgendwas ala BitInteger. Muss aber keine Library sein die beliebig grosse Zahlen unterstützt, 128 Bit reichen locker. So lange du den Datentyp allerdings nicht direkt zur Serialisierung bzw. für binären Datenaustausch verwendest, wird es auch reichen wenn du dir ne hübsch gekapselte MonetaryAmount Klasse machst. Die kann dann intern erstmal long long verwenden. Und falls du jemals ein Problem mit dem eingeschränkten Zahlenbereich bekommst (was vermutlich nie passieren wird), kannst du es relativ easy an einer Stelle umstellen.



  • Wird Zeit für´n Split.


  • Mod

    NeugierGEAR schrieb:

    Schlangenmensch schrieb:

    Du kannst so viel runden wie du willst, du kommst trotzdem nicht näher an die Darstellung von 0.001. Und, was passiert wenn du eine ungenaue Darstellung von 0.001 (irgendwas wie 0.009987564) mit einer ungenauen Darstellung von 100 multiplizierst?
    Die Repräsentation von Floatingpoint zahlen, ist dafür einfach nicht geeignet.

    Richtig!

    Ich habe nur auf die plumpe Antwort von SeppJ eine Antwort gegeben. Somit hat er sein Cent.

    Moment, deine Antwort war ernst? Ich dachte das sei ein Scherz. Es ist doch offensichtlich, dass es wichtig ist, dass ein Cent auch genau ein Cent ist, weil sonst die Summe von genügend vielen Cents eben nicht mehr genau das ist, was man so denkt. Wo dir auch kein Runden hilft.

    Oder etwas praxisnäher, da der Effekt größer ist: Differenzen. Da explodiert dir der relative Fehler der Berechnung. Zahl eine Rechnung in mehreren Raten und wunder dich, wieso du später eine Mahnung bekommst, weil du aufgrund der akkumulierten Fehler zu wenig gezahlt hast.



  • hustbaer schrieb:

    Der COM Standard von Microsoft verwendet für Geldbeträge z.B. 64 Bit Fixkomma mit Faktor 10000.

    Da kommst du bei Bitcoins gerade mal auf den Wert von ca. 1 € runter.

    (8915,1691 € pro Bitcoin)


  • Mod

    DirkB schrieb:

    hustbaer schrieb:

    Der COM Standard von Microsoft verwendet für Geldbeträge z.B. 64 Bit Fixkomma mit Faktor 10000.

    Da kommst du bei Bitcoins gerade mal auf den Wert von ca. 1 € runter.

    (8915,1691 € pro Bitcoin)

    Es gibt maximal 21 Millionen Coins, und jede Coin besteht aus 100 Millionen Satoshi. Macht 2.1*10^15 Satoshi. Wenn man also mit den Vorkommastellen des zitierten Standards rechnet, dann kommt man gar nicht aus - eine Stelle zu wenig. Wenn man mit den Nachkommastellen rechnet, dann braucht man die Krücke, dass man nicht in ganzen Bitcoin rechnen kann (weil 5 Nachkommastellen nicht reichen, um die einzelnen Satoshi zu erfassen), sondern in bit (millionstel Bitcoins). Ziemlich krude Krücke, da schließlich entweder Satoshi oder Bitcoins die natürlichen Einheiten wären.

    Wobei man gerechterweise sagen muss, dass auch so ziemlich jede andere Währung auf der Welt das erste Problem hätte, wenn man ihren Gesamtbestand aufaddieren würde. Denn 900 Milliarden von egal welcher Währung ist normalerweise nicht genug, um deren Gesamtbestand zu erfassen. Im wirklichen Leben wird diese Zahl bloß niemals irgendwo auftauchen, weil man diese Information bei "normalen" Währungen nie brauchen wird. Bei Bitcoin ist hingegen denkbar, dass man diese Zahl durchaus mal irgendwo darstellen möchte, denn anders als bei "normalen" Währungen ist die Gesamtmenge aller Bitcoins exakt bekannt und kann daher in irgendwelche Rechnungen einfließen (a la "Ich besitze X% alle Bitcoins").



  • DirkB schrieb:

    hustbaer schrieb:

    Der COM Standard von Microsoft verwendet für Geldbeträge z.B. 64 Bit Fixkomma mit Faktor 10000.

    Da kommst du bei Bitcoins gerade mal auf den Wert von ca. 1 € runter.

    (8915,1691 € pro Bitcoin)

    OK. Was willst du mir damit sagen? Und hast du auch den Rest meines Beitrags gelesen?


Anmelden zum Antworten