Frage

Ich kann nennen Sie drei Vorteile der Verwendung double (oder float) anstelle von decimal:

  1. Nutzt weniger Speicher.
  2. Schneller, weil die Gleitkomma-Mathematik Operationen nativ unterstützt werden die Prozessoren.
  3. Darstellen kann einen größeren Bereich von zahlen.

Aber diese Vorteile scheinen, gelten nur für die Berechnung intensive Operationen, wie Sie in modeling software.Natürlich verdoppelt sich, sollten Sie nicht verwendet werden, wenn Präzision erforderlich ist, wie finanzielle Berechnungen.So gibt es praktische Gründe, immer wählen double (oder float) anstelle von decimal in "normalen" Anwendungen?

Bearbeitet, um hinzufügen:Danke für all die tollen Reaktionen, die ich von Ihnen gelernt.

Eine weitere Frage:Ein paar Leute gemacht, die zeigen, dass Doppelzimmer kann mehr genau repräsentieren reelle zahlen.Wenn deklariert, ich würde denken, dass Sie in der Regel mehr genau repräsentieren Sie als gut.Aber es ist eine wahre Aussage, dass die Genauigkeit verringern (manchmal erheblich) bei der floating-point-Operationen durchgeführt werden?

War es hilfreich?

Lösung

Ich glaube, Sie die Vorteile ganz gut zusammengefasst haben. Sie fehlen jedoch einen Punkt. Der decimal Typ ist nur genauer zu repräsentieren Basis (die zB in der Währung / Finanzberechnungen verwendet) 10 Zahlen. Im Allgemeinen wird die double Art zumindest bieten als großer Präzision (jemand korrigiert mich wenn ich falsch liege) und auf jeden Fall eine höhere Geschwindigkeit für beliebige reelle Zahlen. Die einfache Schlussfolgerung:. Wenn man bedenkt, was immer zu verwenden, verwenden Sie double, wenn Sie die base 10 Genauigkeit benötigen, die Angebote decimal

Edit:

In Bezug auf Ihre weitere Frage nach der Abnahme der Genauigkeit von Gleitkommazahlen nach Operationen, ist dies eine etwas subtilere Frage. Tatsächlich Präzision (Ich verwende den Begriff synonym für Genauigkeit hier) wird stetig abnehmen nach jeder Operation ausgeführt wird. Dies ist aus zwei Gründen:

  1. die Tatsache, dass bestimmte Zahlen (die meisten offensichtlich Dezimalstellen) nicht wirklich in Gleitkomma-Form dargestellt werden
  2. Rundungsfehler auftreten, so als ob Sie die Berechnung von Hand taten. Es hängt stark vom Kontext (wie viele Operationen Sie ausführen), ob diese Fehler jedoch signifikant genug, um zu rechtfertigen viele Gedanken sind.

In allen Fällen, wenn Sie zwei Gleitkommazahlen vergleichen wollen, die in der Theorie äquivalent sein sollten (aber mit unterschiedlichen Berechnungen wurden angekommen), benötigen Sie ein gewisses Maß an Toleranz zu ermöglichen (wie viel variiert, ist aber typischerweise sehr klein).

Für eine detailliertere Übersicht über die besonderen Fälle, in denen Fehler in Genauigkeiten eingebracht werden können, finden Sie in der Genauigkeit Abschnitt der Wikipedia-Artikel . Schließlich, wenn Sie eine ernsthaft in-Tiefe (und mathematische) Diskussion von Gleitkommazahlen / Operationen auf Maschinenebene wollen, versuchen Sie die oft zitierten Artikel lesen Was jeder Informatiker wissen sollten über Gleitkommaarithmetik .

Andere Tipps

Sie scheinen an Ort und Stelle mit die Vorteile der Verwendung einer floating-point-Typ.Ich Neige dazu, design für Dezimalzahlen in allen Fällen, und verlassen sich auf ein profiler zu lassen Sie mich wissen, wenn Operationen auf dezimal verursacht Engpässe oder slow-downs.In diesen Fällen werde ich "down-cast" auf Doppel-oder schwimmen, aber nur intern, und versuchen Sie vorsichtig zu verwalten, Präzision Verlust durch die Begrenzung der Anzahl der signifikanten stellen in der mathematischen operation, die durchgeführt wird.

Im Allgemeinen, wenn Ihr Wert ist transient (nicht wiederverwendet), Sie sind sicher zu verwenden eine floating-point-Typ.Das eigentliche problem mit floating-point-Typen die folgenden drei Szenarien.

  1. Sie sind aggregiert floating point Werte (in dem Fall die Genauigkeit Fehler compound)
  2. Sie bauen auf Werte basierend auf den floating-point-Wert (beispielsweise in einem rekursiven Algorithmus)
  3. Sie sind dabei math mit einer sehr breiten Anzahl der signifikanten stellen (zum Beispiel, 123456789.1 * .000000000000000987654321)

BEARBEITEN

Nach der Referenz-Dokumentation über die C# - Dezimalzahlen:

Die dezimal Stichwort kennzeichnet eine 128-bit-Datentyp.Im Vergleich zu floating-point-Typen, der decimal-Typ hat eine größere Präzision und eine kleinere Palette, die macht es geeignet für Finanz-und Währungs-Berechnungen.

Um zu klären, meine obige Aussage:

Ich Neige dazu, design für Dezimalzahlen in allen Fällen, und verlassen sich auf ein profiler zu lassen mich wissen, wenn Operationen auf dezimal ist Engpässen oder slow-downs.

Ich habe immer nur gearbeitet, in Branchen, in denen Dezimalzahlen sind günstig.Wenn Sie arbeiten, phsyics oder Grafik-engines, ist es wahrscheinlich sehr viel günstiger zu design für einen Gleitkommawert (float oder double).

Dezimal ist nicht unendlich präzise (es ist unmöglich zu vertreten unendliche Genauigkeit für nicht-integral-in einen primitiven Datentyp), aber es ist weit mehr genaue als das doppelte:

  • dezimal = 28-29 signifikante stellen
  • double = 15-16 signifikante stellen
  • float = 7 signifikante Ziffern

BEARBEITEN 2

In Antwort auf Konrad Rudolph's Kommentar, item # 1 (oben) ist auf jeden Fall richtig.Aggregation von Ungenauigkeiten tatsächlich in Verbindung.Siehe den code unten für ein Beispiel:

private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;

public static void Main(string[] args)
{
    Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
    float asSingle = 0f;
    double asDouble = 0d;
    decimal asDecimal = 0M;

    for (int i = 0; i < ONE_MILLION; i++)
    {
        asSingle += THREE_FIFTHS;
        asDouble += THREE_FIFTHS;
        asDecimal += (decimal) THREE_FIFTHS;
    }
    Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
    Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
    Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
    Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
    Console.ReadLine();
}

Dies gibt Folgendes aus:

Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000

Wie Sie sehen können, auch wenn wir hinzufügen aus der gleichen Quelle Konstante, die Ergebnisse der Doppel-weniger präzise (wenn auch wahrscheinlich wird die Runde nicht richtig), und der Schwimmer ist weit weniger präzise, auf den Punkt, wo es reduziert wurde, um nur zwei signifikante Ziffern.

Verwendung für dezimale Basis 10 Werte, z.B. Finanz-Berechnungen, wie andere vorgeschlagen haben.

Aber doppelt ist in der Regel genauer für beliebige berechnete Werte.

Wenn Sie zum Beispiel das Gewicht jeder Zeile in einem Portfolio berechnen möchten, verwenden Sie doppelt als das Ergebnis mehr wird fast zu 100% addieren.

Im folgende Beispiel doubleResult näher an 1 als decimalResult:

// Add one third + one third + one third with decimal
decimal decimalValue = 1M / 3M;
decimal decimalResult = decimalValue + decimalValue + decimalValue;
// Add one third + one third + one third with double
double doubleValue = 1D / 3D;
double doubleResult = doubleValue + doubleValue + doubleValue;

Also noch einmal das Beispiel eines Portfolios unter:

  • Der Marktwert jeder Zeile im Portfolio ist ein Geld-Wert und wahrscheinlich am besten als Dezimalzahl dargestellt werden würde.

  • Das Gewicht jeder Zeile im Portfolio (= Marktwert / SUM (Marktwert)) ist in der Regel besser als doppelt dargestellt.

Verwenden Sie einen Doppel- oder einen Schwimmer, wenn Sie Präzision nicht benötigen, beispielsweise in einem Jump'n'Run Spiel, das ich geschrieben habe, habe ich einen Schwimmer die Spieler Geschwindigkeiten zu speichern. Offensichtlich kann ich nicht super Präzision brauchen hier, weil ich schließlich Runde auf ein Int für Zeichnen auf dem Bildschirm.

In einigen Rechnungswesen, die Möglichkeit prüfen integrale Typen anstelle oder in Verbindung. Nehmen wir zum Beispiel sagen, dass die Regeln unter Ihnen jedes Berechnungsergebnis vortragen mit mindestens 6 Dezimalstellen und das Endergebnis wird auf den nächsten Cent arbeiten erfordern gerundet werden.

Eine Berechnung von 1/6 von $ 100 $ ergibt 16,66666666666666 ..., so erfolgt der Wert weiter in einem Arbeitsblatt wird $ 16,666667 sein. Beide Doppel und dezimal sollte dieses Ergebnis genau zu 6 Dezimalstellen ergeben. Jedoch können wir keine kumulativen Fehler vermeiden, indem das Ergebnis nach vorne als eine ganzen Zahl 16666667. Jede nachfolgende Berechnung trägt, kann mit der gleichen Präzision und Vortrag in ähnlicher Weise hergestellt werden. Fortsetzung des Beispiels, berechne ich Verkäufe Texas Steuer auf diesen Betrag (16666667 * 0,0825 = 1.375.000). Das Hinzufügen der zwei (es ist nur eine kurze Arbeitsblatt) 1.666.667 + 1.375.000 = 18041667. die Dezimalpunkt Umzug zurück in gibt uns 18,041667, oder $ 18.04.

Während dieses kurze Beispiel würde keinen kumulativen Fehler ergibt Doppel- oder dezimal verwendet, ist es ziemlich einfach Fälle zu zeigen, wo einfach die doppelten oder dezimal Berechnung und Vortragen signifikante Fehler ansammeln würde. Wenn die Regeln unter Sie eine begrenzte Anzahl von Dezimalstellen erfordern arbeiten, wobei jeder Wert als eine ganze Zahl speichert, die von mit 10 ^ (erforderliche Anzahl Dezimalstelle) multipliziert und dann mit 10 ^ (erforderliche Anzahl der Dezimalstellen) Dividieren erhalten die eigentliche Wert wird jeden kumulativen Fehler vermeiden.

In Situationen, in denen Anteile von einem paar Cent nicht auftreten (zum Beispiel ein Verkaufsautomat), gibt es keinen Grund, nicht-ganzzahligen Typen überhaupt zu benutzen. Einfach daran zu denken als das Zählen ein paar Cent, nicht Dollar. Ich habe Code gesehen, wo jede Berechnung nur ganze Pennies beteiligt, doch die Verwendung von Doppel zu Fehlern geführt! Integer nur Mathe entfernt, um das Problem. Also meine unkonventionelle Antwort ist, wenn möglich, verzichten beide Doppel-und dezimal.

Wenn Sie interrop mit anderen Sprachen oder Plattformen Binär benötigen, dann könnten Sie müssen float oder double verwendet werden, die standardisiert sind.

Hinweis: Dieser Beitrag basiert auf Informationen von den Fähigkeiten des Dezimal-Typ von http: // csharpindepth. com / Artikel / Allgemein / Decimal.aspx und meine eigene Interpretation dessen, was das bedeutet. Ich gehe davon aus Doppel ist normal IEEE doppelte Genauigkeit.

Hinweis 2:. Kleinsten und größten in diesem Beitrag reffer auf die Größe der Zahl

Pros von "Dezimal".

  • „dezimal“ kann genau Zahlen darstellen, die als (ausreichend kurz) Dezimalbrüchen geschrieben werden kann, doppelt nicht. Dies ist wichtig, in finanziellen Riegeln und ähnlich denen es wichtig ist, dass die Ergebnisse genau dem entsprechen, was ein Mensch die Berechnungen tun würde.
  • „dezimal“ hat eine viel größere Mantisse als „double“. Das bedeutet, dass für Werte er innerhalb der normierten Bereich „dezimal“ eine wesentlich höhere Präzision als das Doppelte haben.

Nachteile von dezimal

  • Es wird viel langsamer (ich habe Benchmarks nicht, aber ich würde zumindest eine Größenordnung vielleicht mehr erraten), dezimal wird nicht von jeder Hardware-Beschleunigung und Arithmetik zugute kommt auf sie relativ teuer Multiplikation / Division durch Potenzen erfordern von 10 (was auch viel teurer als Multiplikation und dividion durch Potenzen von 2) den Exponenten vor Addition / Subtraktion anzupassen und die Exponenten wieder in Reichweite nach Multiplikation / Division zu bringen.
  • dezimal wird früher tha Doppelüberläuft. dezimal kann nur Zahlen stellen bis 2 bis ± 96 -1. Durch Vergleich kann doppelte Zahlen stellen bis zu fast ± 2 1024
  • dezimal wird früher unterlaufen. Die kleinsten Zahlen darstellbare in dezimal sind ± 10 -28 . Durch Vergleich kann doppelte Werte stellen bis zu 2 -149 (ca. 10 -45 ), wenn subnromal Nummern unterstützt und 2 -126 (ca. 10 -38 ), wenn sie nicht sind.
  • dezimal dauert doppelt so viel Speicher wie doppelt auf.

Meine Meinung ist, dass Sie mit „dezimal“ für Geld arbeiten und in anderen Fällen in Verzug, wo genau die menschliche Berechnung passend ist wichtig, und dass Sie die Verwendung doppelt als Standard-Wahl, um den Rest der Zeit verwendet werden soll.

Verwenden floating Punkte, wenn Sie die Leistung über Richtigkeit schätzen.

Wählen Sie die Art in Funktion der Anwendung. Wenn Sie Präzision wie in der Finanzanalyse benötigen, haben Sie Ihre Frage beantwortet. Aber wenn Ihre Anwendung mit einer Schätzung Ihres ok mit Doppel absetzen kann.

Ist Ihre Anwendung in der Notwendigkeit einer schnellen Berechnung oder wird er die ganze Zeit in der Welt, die Ihnen eine Antwort zu geben? Es hängt wirklich von der Art der Anwendung.

Grafik hungrig? schwimmen oder doppelt so hoch ist genug. Finanzdatenanalyse, Meteor einen Planeten Art von Präzision schlagen? Diejenigen, würde ein wenig Präzision benötigen:)

Dezimal hat breiteres Bytes, Doppel wird nativ von CPU unterstützt. Dezimal ist Basis 10, so dass eine Dezimal-Doppelwandlung geschieht, während eine Dezimalzahl berechnet wird.

For accounting - decimal
For finance - double
For heavy computation - double

Beachten Sie .NET CLR unterstützt nur Math.Pow (double, double). Dezimal wird nicht unterstützt.

.NET Framework 4

[SecuritySafeCritical]
public static extern double Pow(double x, double y);

Ein Doppel Werte werden auf wissenschaftliche Schreibweise standardmäßig serialisiert, wenn die Schreibweise kürzer als die Dezimal-Anzeige ist. Dezimalwerte (z 0,00000003 wird 3e-8) werden nicht an die wissenschaftliche Schreibweise serialisiert. Wenn für den Verzehr durch eine externe Partei Serialisierung, kann dies eine Überlegung sein.

Hängt davon ab, was Sie brauchen es für.

Da float und double sind binäre Datentypen Sie haben einige diifculties und errrors in der Art und Weise in den Runden Zahlen, so zum Beispiel Doppel würde 0,1-,100000001490116 runden, verdoppeln auch Runde 1/3 0,33333334326441. Einfach gesagt nicht alle reellen Zahlen haben genaue Darstellung in Doppeltypen

Zum Glück C # unterstützt auch die sogenannte Fliesskommaarithmetik, wo Zahlen über das Dezimalsystem Zahlensystem dargestellt sind, anstatt das binäre System. Somit schwimmend die Komma-Arithmetik keine Genauigkeit verlieren bei der Lagerung und Verarbeitung von Fließkommazahlen. Dies macht es ungemein Berechnungen geeignet, bei denen ein hohes Maß an Genauigkeit erforderlich ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top