Ich kann drei Vorteile für die Verwendung double
(oder float
) anstelle von nennen decimal
:
- Verbraucht weniger Speicher.
- Schneller, da Gleitkomma-Mathematikoperationen von Prozessoren nativ unterstützt werden.
- Kann einen größeren Zahlenbereich darstellen.
Diese Vorteile scheinen jedoch nur für rechenintensive Operationen zu gelten, wie sie beispielsweise in Modellierungssoftware zu finden sind. Natürlich sollten Doppelbilder nicht verwendet werden, wenn Präzision erforderlich ist, z. B. bei Finanzberechnungen. Gibt es also praktische Gründe, sich jemals für double
(oder float
) anstatt für decimal
"normale" Anwendungen zu entscheiden?
Bearbeitet, um hinzuzufügen: Danke für all die tollen Antworten, die ich von ihnen gelernt habe.
Eine weitere Frage: Einige Leute haben darauf hingewiesen, dass Doppelte reelle Zahlen genauer darstellen können. Wenn erklärt, würde ich denken, dass sie sie normalerweise auch genauer darstellen. Aber ist es eine wahre Aussage, dass die Genauigkeit (manchmal erheblich) abnehmen kann, wenn Gleitkommaoperationen ausgeführt werden?
Antworten:
Ich denke, Sie haben die Vorteile recht gut zusammengefasst. Ihnen fehlt jedoch ein Punkt. Der
decimal
Typ ist nur bei der Darstellung von Basis-10- Zahlen genauer (z. B. diejenigen, die in Währungs- / Finanzberechnungen verwendet werden). Im Allgemeinen bietet derdouble
Typ mindestens die gleiche Präzision (jemand korrigiert mich, wenn ich falsch liege) und definitiv eine höhere Geschwindigkeit für beliebige reelle Zahlen. Die einfache Schlussfolgerung lautet: Wenn Sie überlegen, welchedouble
Sie verwenden möchten, verwenden Sie sie immer, es sei denn, Sie benötigen diebase 10
Genauigkeit, die siedecimal
bietet.Bearbeiten:
In Bezug auf Ihre zusätzliche Frage zur Verringerung der Genauigkeit von Gleitkommazahlen nach Operationen ist dies ein etwas subtileres Problem. Tatsächlich nimmt die Präzision (ich verwende den Begriff hier austauschbar für Genauigkeit) nach jeder Operation stetig ab. Dies hat zwei Gründe:
Wenn Sie zwei Gleitkommazahlen vergleichen möchten, die theoretisch äquivalent sein sollten (aber mit unterschiedlichen Berechnungen ermittelt wurden), müssen Sie in allen Fällen einen bestimmten Toleranzgrad zulassen (wie stark variiert, ist aber normalerweise sehr klein). .
Eine detailliertere Übersicht über die besonderen Fälle, in denen Genauigkeitsfehler auftreten können, finden Sie im Abschnitt Genauigkeit des Wikipedia-Artikels . Wenn Sie eine ausführliche (und mathematische) Diskussion über Gleitkommazahlen / -operationen auf Maschinenebene wünschen, lesen Sie den oft zitierten Artikel Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte .
quelle
double
. Moderne Computer drucken immer noch den richtigen Wert, aber nur, weil sie das Ergebnis „erraten“ - nicht, weil es wirklich richtig ausgedrückt wird.Decimal
Typ hat eine Genauigkeit von 93 Bit in der Mantisse, verglichen mit etwa 52 Bit fürdouble
. Ich wünschte, Microsoft würde das IEEE 80-Bit-Format unterstützen, auch wenn es auf 16 Byte aufgefüllt werden müsste. es hätte eine größere Reichweite alsdouble
oder eineDecimal
viel bessere Geschwindigkeit als dieDecimal
Unterstützung für transzendentale Operationen (z. B. sin (x), log (x) usw.) und Präzision ermöglicht, die zwar nicht ganz so gut sind, wieDecimal
es viel besser wäre alsdouble
.Sie scheinen die Vorteile der Verwendung eines Gleitkommatyps genau zu kennen. Ich neige in allen Fällen dazu, für Dezimalstellen zu entwerfen, und verlasse mich auf einen Profiler, der mich darüber informiert, ob Operationen mit Dezimalstellen Engpässe oder Verlangsamungen verursachen. In diesen Fällen werde ich "down cast", um zu verdoppeln oder zu schweben, aber nur intern, und sorgfältig versuchen, den Präzisionsverlust zu verwalten, indem ich die Anzahl der signifikanten Stellen in der ausgeführten mathematischen Operation beschränke.
Wenn Ihr Wert vorübergehend ist (nicht wiederverwendet wird), können Sie im Allgemeinen einen Gleitkommatyp verwenden. Das eigentliche Problem bei Gleitkommatypen sind die folgenden drei Szenarien.
123456789.1 * .000000000000000987654321
)BEARBEITEN
Gemäß der Referenzdokumentation zu C # -Dezimalzahlen :
Um meine obige Aussage zu verdeutlichen:
Ich habe immer nur in Branchen gearbeitet, in denen Dezimalstellen günstig sind. Wenn Sie an Phsyics- oder Grafik-Engines arbeiten, ist es wahrscheinlich viel vorteilhafter, für einen Gleitkommatyp (Float oder Double) zu entwerfen.
Dezimal ist nicht unendlich genau (es ist unmöglich, unendliche Genauigkeit für Nicht-Integral in einem primitiven Datentyp darzustellen), aber es ist weitaus genauer als doppelt:
BEARBEITEN 2
Als Antwort auf den Kommentar von Konrad Rudolph ist Punkt 1 (oben) definitiv richtig. Die Aggregation von Ungenauigkeiten verstärkt sich tatsächlich. Ein Beispiel finden Sie im folgenden Code:
Dies gibt Folgendes aus:
Wie Sie sehen können, sind die Ergebnisse des Doppelten weniger genau (obwohl sie wahrscheinlich korrekt gerundet werden), obwohl wir aus derselben Quellenkonstante addieren, und der Float ist weitaus ungenauer, bis zu dem Punkt, an dem er nur auf reduziert wurde zwei signifikante Ziffern.
quelle
Single: 667660.400000000000
während der Dezimalwert ergabDecimal: 666666.7000000000
. Der Float-Wert liegt etwas unter tausend über dem korrekten Wert.Verwenden Sie Dezimalzahlen für Basis-10-Werte, z. B. Finanzberechnungen, wie andere vorgeschlagen haben.
Für beliebig berechnete Werte ist double im Allgemeinen genauer.
Wenn Sie beispielsweise das Gewicht jeder Zeile in einem Portfolio berechnen möchten, verwenden Sie double, da das Ergebnis nahezu 100% ergibt.
Im folgenden Beispiel liegt doubleResult näher an 1 als decimalResult:
Nehmen wir also noch einmal das Beispiel eines Portfolios:
Der Marktwert jeder Zeile im Portfolio ist ein Geldwert und wird wahrscheinlich am besten als Dezimalzahl dargestellt.
Das Gewicht jeder Zeile im Portfolio (= Marktwert / SUMME (Marktwert)) wird normalerweise besser als doppelt dargestellt.
quelle
Verwenden Sie ein Double oder einen Float, wenn Sie keine Präzision benötigen. In einem von mir geschriebenen Platformer-Spiel habe ich beispielsweise einen Float verwendet, um die Geschwindigkeiten der Spieler zu speichern. Offensichtlich brauche ich hier keine Superpräzision, weil ich schließlich zu einem Int runde, um auf dem Bildschirm zu zeichnen.
quelle
Berücksichtigen Sie in einigen Buchhaltungsverfahren die Möglichkeit, stattdessen oder in Verbindung integrale Typen zu verwenden. Angenommen, die Regeln, nach denen Sie arbeiten, erfordern, dass jedes Berechnungsergebnis mit mindestens 6 Dezimalstellen übertragen wird und das Endergebnis auf den nächsten Cent gerundet wird.
Eine Berechnung von 1/6 von 100 US-Dollar ergibt 16,666666666666666 ..., sodass der in einem Arbeitsblatt angegebene Wert 16,6666667 US-Dollar beträgt. Sowohl Doppel- als auch Dezimalstellen sollten dieses Ergebnis auf 6 Dezimalstellen genau ergeben. Wir können jedoch jeden kumulativen Fehler vermeiden, indem wir das Ergebnis als Ganzzahl 16666667 übertragen. Jede nachfolgende Berechnung kann mit derselben Genauigkeit durchgeführt und auf ähnliche Weise übertragen werden. Wenn ich das Beispiel fortsetze, berechne ich die Umsatzsteuer in Texas auf diesen Betrag (16666667 * .0825 = 1375000). Addieren der beiden (es ist ein kurzes Arbeitsblatt) 1666667 + 1375000 = 18041667. Wenn Sie den Dezimalpunkt wieder nach innen verschieben, erhalten Sie 18.041667 oder $ 18.04.
Während dieses kurze Beispiel keinen kumulativen Fehler mit Doppel- oder Dezimalzahlen ergeben würde, ist es ziemlich einfach, Fälle zu zeigen, in denen das einfache Berechnen der Doppel- oder Dezimalzahl und das Weitertragen einen signifikanten Fehler akkumulieren würden. Wenn für die Regeln, nach denen Sie arbeiten, eine begrenzte Anzahl von Dezimalstellen erforderlich ist, speichern Sie jeden Wert als Ganzzahl, indem Sie mit 10 ^ (erforderliche Anzahl von Dezimalstellen) multiplizieren und dann durch 10 ^ (erforderliche Anzahl von Dezimalstellen) dividieren, um die tatsächliche zu erhalten Wert vermeidet kumulative Fehler.
In Situationen, in denen Bruchteile von Pennys nicht vorkommen (z. B. ein Verkaufsautomat), gibt es keinen Grund, überhaupt nicht integrale Typen zu verwenden. Stellen Sie sich das einfach so vor, als würden Sie ein paar Cent zählen, nicht Dollar. Ich habe Code gesehen, bei dem jede Berechnung nur ganze Pennys umfasste, aber die Verwendung von Double zu Fehlern führte! Nur ganzzahlige Mathematik hat das Problem behoben. Meine unkonventionelle Antwort lautet also, wenn möglich, auf Doppel- und Dezimalzahlen zu verzichten.
quelle
Wenn Sie binäres Interrop mit anderen Sprachen oder Plattformen benötigen, müssen Sie möglicherweise float oder double verwenden, die standardisiert sind.
quelle
Hinweis: Dieser Beitrag basiert auf Informationen zu den Funktionen des Dezimaltyps von http://csharpindepth.com/Articles/General/Decimal.aspx und meiner eigenen Interpretation dessen, was dies bedeutet. Ich gehe davon aus, dass Double eine normale IEEE-Doppelgenauigkeit ist.
Anmerkung 2: Kleinste und größte in diesem Beitrag beziehen sich auf die Größe der Zahl.
Vorteile von "dezimal".
Nachteile der Dezimalstelle
Meiner Meinung nach sollten Sie standardmäßig "Dezimal" für Geldarbeit und andere Fälle verwenden, in denen eine genaue Übereinstimmung der menschlichen Berechnung wichtig ist, und Sie sollten für den Rest der Zeit das Doppelte als Standardauswahl verwenden.
quelle
Kommt darauf an, wofür du es brauchst.
Da float und double binäre Datentypen sind, gibt es in Rundenzahlen einige Schwierigkeiten und Fehler, sodass double beispielsweise 0,1 auf 0,100000001490116 rundet und double auch 1/3 auf 0,33333334326441 rundet. Einfach gesagt, nicht alle reellen Zahlen haben eine genaue Darstellung in doppelten Typen
Glücklicherweise unterstützt C # auch die sogenannte Dezimal-Gleitkomma-Arithmetik, bei der Zahlen eher über das Dezimalzahlensystem als über das Binärsystem dargestellt werden. Somit verliert die dezimale Gleitkomma-Arithmetik beim Speichern und Verarbeiten von Gleitkommazahlen nicht an Genauigkeit . Dies macht es immens geeignet für Berechnungen, bei denen ein hohes Maß an Genauigkeit erforderlich ist.
quelle
Verwenden Sie Gleitkommawerte, wenn Sie Leistung über Korrektheit bewerten.
quelle
Wählen Sie den Funktionstyp Ihrer Anwendung. Wenn Sie Präzision wie bei der Finanzanalyse benötigen, haben Sie Ihre Frage beantwortet. Aber wenn Ihre Bewerbung mit einer Schätzung abrechnen kann, ist Ihr OK mit Double.
Benötigt Ihre Bewerbung eine schnelle Berechnung oder hat er weltweit die Zeit, Ihnen eine Antwort zu geben? Es hängt wirklich von der Art der Anwendung ab.
Grafik hungrig? float oder double ist genug. Finanzdatenanalyse, Meteor trifft einen Planeten mit Präzision? Die würden ein bisschen Präzision brauchen :)
quelle
Dezimal hat breitere Bytes, double wird von der CPU nativ unterstützt. Dezimal ist Basis-10, daher findet eine Dezimal-zu-Doppel-Konvertierung statt, während eine Dezimalzahl berechnet wird.
Beachten Sie, dass .NET CLR nur Math.Pow (double, double) unterstützt. Dezimal wird nicht unterstützt.
.NET Framework 4
quelle
Ein Doppelwert wird standardmäßig in die wissenschaftliche Notation serialisiert, wenn diese Notation kürzer als die Dezimalanzeige ist. (z. B. .00000003 ist 3e-8) Dezimalwerte werden niemals in wissenschaftliche Notation serialisiert. Bei der Serialisierung für den Verbrauch durch eine externe Partei kann dies eine Überlegung sein.
quelle