57 Stimmen

Dezimal vs. Doppelte Geschwindigkeit

Ich schreibe Finanzanwendungen, bei denen ich ständig vor der Entscheidung stehe, ob ich ein Double oder eine Dezimalzahl verwenden soll.

Ich rechne immer mit Zahlen, die nicht mehr als 5 Dezimalstellen haben und nicht größer als ~100.000 sind. Ich habe das Gefühl, dass alle diese Zahlen ohne Rundungsfehler als Potenzen dargestellt werden können, aber ich war mir nie sicher.

Ich würde die Umstellung von Dezimalzahlen auf Paschalzahlen wegen des offensichtlichen Geschwindigkeitsvorteils vornehmen, aber letztendlich verwende ich immer noch die ToString-Methode, um die Preise an die Börsen zu übermitteln, und muss sicherstellen, dass sie immer die erwartete Zahl ausgibt. (89,99 statt 89,99000000001)

Fragen:

  1. Ist der Geschwindigkeitsvorteil wirklich so groß, wie naive Tests vermuten lassen? (~100 mal)
  2. Gibt es eine Möglichkeit, die Ausgabe von ToString zu garantieren, was ich will? Ist dies durch die Tatsache gewährleistet, dass meine Zahl immer darstellbar ist?

UPDATE: Ich habe ~ 10 Milliarden Preisaktualisierungen zu verarbeiten, bevor meine App laufen kann, und ich habe mit dezimalen jetzt für die offensichtliche Schutzgründe implementiert, aber es dauert ~ 3 Stunden, nur um einzuschalten, würde das Doppelte meine Einschaltzeit dramatisch reduzieren. Gibt es einen sicheren Weg, um es mit Verdoppelungen zu tun?

1 Stimmen

Was ist Ihr Engpass? Wo genau verbrauchen Sie alle Ihre CPU-Zyklen? Ohne solide Messungen ist die Wahrscheinlichkeit groß, dass Sie sich mit der völlig falschen Sache beschäftigen.

4 Stimmen

Da dezimale Nenner Potenzen von 10 und binäre Nenner Potenzen von 2 sind, kann nicht einmal 1 Dezimalstelle fehlerfrei dargestellt werden. Zum Beispiel hat 0,1 (ein Zehntel) keine exakte Entsprechung im Binärsystem, was dem gleichen Prinzip entspricht, dass es für ein Drittel keine exakte Darstellung im Dezimalsystem gibt.

6voto

mezoid Punkte 27286

Bei finanziellen Berechnungen sollten immer Dezimalzahlen verwendet werden. Die Größe der Zahlen ist nicht wichtig.

Am einfachsten kann ich das anhand von C#-Code erklären.

double one = 3.05;
double two = 0.05;

System.Console.WriteLine((one + two) == 3.1);

Dieses Stück Code gibt Folgendes aus Falsch auch wenn 3,1 gleich 3,1 ist...

Das Gleiche... aber mit Dezimalzahlen:

decimal one = 3.05m;
decimal two = 0.05m;

System.Console.WriteLine((one + two) == 3.1m);

Dies wird nun ausgedruckt Wahr !

Wenn Sie diese Art von Problemen vermeiden wollen, empfehle ich Ihnen, bei Dezimalzahlen zu bleiben.

1 Stimmen

Was wirklich ärgerlich ist, ist, dass die .NET ToString()-Methoden nicht in der Lage zu sein scheinen, diese Differenz anzuzeigen, selbst wenn man sie auffordert, bis zu 20 Dezimalstellen anzuzeigen. Wenn Sie die Zahlen subtrahieren, können Sie sehen, dass es etwa 4.44E-16 Unterschied zwischen ihnen gibt... aber ich sehe nirgendwo eine 4 in der Zeichenkette "3.10000000000000000000", die von der ToString-Methode ausgegeben wird. Wenn Sie BitConverter.ToString( BitConverter.GetBytes( one + two )) und dasselbe für (3.1) verwenden, dann sind die Bytes tatsächlich unterschiedlich (CD-CC-CC-CC-CC-CC-08-40 vs. CC-CC-CC-CC-CC-08-40), aber double.ToString() zeigt dies nicht an!

3 Stimmen

Wenn man die richtige Skalierung verwendet und gut definierte Rundungsregeln hat, double kann genauso präzise sein wie decimal . Wenn man keine genauen Rundungsregeln hat, decimal haben oft die gleichen Probleme wie double . Wenn zum Beispiel drei Personen jeweils hundert Artikel kaufen, die zum Preis von "3 für 5 $" verkauft werden, wie viel Geld sollte man dann erhalten?

0 Stimmen

Dies beantwortet keine der Fragen, die der Auftraggeber gestellt hat.

1voto

gbjbaanb Punkte 50303

Ich verweise Sie auf meine Antwort an diese Frage .

Verwenden Sie einen Long, speichern Sie die kleinste Menge, die Sie verfolgen müssen, und zeigen Sie die Werte entsprechend an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X