Das Dezimalschlüsselwort gibt einen 128-Bit-Datentyp an. Im Vergleich zu Gleitkommatypen weist der Dezimaltyp eine höhere Genauigkeit und einen kleineren Bereich auf, wodurch er für finanzielle und monetäre
Berechnungen geeignet ist .
Sie können eine Dezimalstelle wie folgt verwenden:
Sie sollten erklären, was an diesem Link wichtig ist. Eine Antwort sollte für sich allein gut genug sein, mit einem Link als zusätzlicher Referenz oder Detail. Siehe stackoverflow.com/help/how-to-answer
TheRubberDuck
2
Die Antwort mit der Mindestlänge kann also weniger Zeichen enthalten als der Kommentar mit der Mindestlänge - interessant! Nicht, dass ich ein Problem mit der knappen / prägnanten Antwort habe, besonders wenn sie auch "tief" ist, da sie auf weitere Diskussionen verweist.
B. Clay Shannon
3
Erstaunliche Antwort, und ich glaube nicht, dass es einer weiteren Erklärung bedarf, da sie die Frage vollständig beantwortet. Der Link zur MSDN-Dokumentation ist für mich ein Bonus. Bravo!
Trnelson
@ Leee Treveil, wie das Geld ist (9.0098) bedeutet 4 Zeichen nach Punkt
Der Dezimalwerttyp repräsentiert Dezimalzahlen im Bereich von positiv 79.228.162.514.264.337.593.543.950.335 bis negativ 79.228.162.514.264.337.593.543.950.335. Der Dezimalwerttyp eignet sich für Finanzberechnungen, bei denen eine große Anzahl signifikanter Integral- und Bruchziffern und keine Rundungsfehler erforderlich sind. Der Dezimaltyp beseitigt nicht die Notwendigkeit einer Rundung. Vielmehr werden Fehler aufgrund von Rundungen minimiert.
Eigentlich wollte ich das vorschlagen, aber ich mache Währung zu einer Klasse, damit ich einen Wechselkurs definieren kann (in Bezug auf eine "Basiswährung", oft den US-Dollar [den ich auf einen Wechselkurs von 1,00 festgelegt habe]).
Ich frage mich, ob ein solcher Typ eine Struktur oder Klasse sein sollte. Eine Dezimalzahl + eine (int) Aufzählung ergibt 20 Bytes. Mein Geld ist immer noch auf Struktur.
Nawfal
Das MoneyNuget hat einen toten Github-Link für die Projektsite, also ... keine Dokumente?
George Mauer
Das Problem dabei ist, dass Sie beim Erstellen Ihrer eigenen Implementierung herausfinden müssen, wie Sie diese tatsächlich beibehalten können. Und das beliebteste ORM (EF) unterstützt überhaupt keine benutzerdefinierten Datentypen. Deshalb wird jemand gebeten, wirklich tief in das Unkraut einzudringen, um das zu tun, was ziemlich einfach sein sollte.
George Mauer
25
Dezimal. Wenn Sie Double wählen, sind Sie offen für Rundungsfehler
@Jess doublekann Rundungsfehler verursachen, da Gleitkomma nicht alle Zahlen exakt darstellen kann (z. B. 0,01 hat keine exakte Darstellung im Gleitkomma). Decimal, Auf der anderen Seite, ist für Zahlen genau . (Der Kompromiss Decimalhat einen kleineren Bereich als Gleitkomma) Gleitkomma kann zu * unbeabsichtigten * Rundungsfehlern führen (z 0.01+0.01 != 0.02. B. ). Decimalkann Ihnen Rundungsfehler geben, aber nur, wenn Sie danach gefragt haben (z. B. Math.Round(0.01+0.02)gibt Null zurück)
Ian Boyd
2
@ IanBoyd: Der Wert "$ 1.57" kann genau dargestellt werden (doppelt) 157. Wenn doubleSkalierung und gegebenenfalls domänenspezifische Rundung verwendet und sorgfältig angewendet werden, kann dies vollkommen präzise sein. Wenn man in seiner Rundung schlampig ist, decimalkann dies zu semantisch falschen Ergebnissen führen (z. B. wenn man mehrere Werte addiert, die auf den nächsten Cent gerundet werden sollen, aber nicht zuerst um sie herum). Das einzig gute daran decimalist, dass die Skalierung integriert ist.
Supercat
1
@supercat, zu diesem Kommentar "Wenn man mehrere Werte addiert, die auf den nächsten Cent gerundet werden sollen, aber nicht zuerst um sie herum", sehe ich nicht, wie ein Float dies lösen würde. Es ist ein Benutzerfehler und hat meiner Meinung nach nichts mit Dezimalstellen zu tun. Ich verstehe den Punkt, aber ich glaube, es wurde verlegt, hauptsächlich weil IanBoyd das spezifiziert hat ... wenn Sie danach fragen.
Sawe
16
Dezimalzahl hat einen kleineren Bereich, aber eine höhere Präzision - damit Sie mit der Zeit nicht all diese Pfennige verlieren!
Stimmen Sie dem Geldmuster zu: Der Umgang mit Währungen ist einfach zu umständlich, wenn Sie Dezimalstellen verwenden.
Wenn Sie eine Währungsklasse erstellen, können Sie dort die gesamte Geldlogik ablegen, einschließlich einer korrekten ToString () - Methode, einer besseren Kontrolle der Parsing-Werte und einer besseren Kontrolle der Divisionen.
Außerdem besteht bei einer Währungsklasse keine Möglichkeit, dass unbeabsichtigt Geld mit anderen Daten verwechselt wird.
Eine andere Option (insbesondere wenn Sie Ihre eigene Klasse rollen) besteht darin, ein int oder ein int64 zu verwenden und die unteren vier Ziffern (oder möglicherweise sogar 2) als "rechts vom Dezimalpunkt" zu kennzeichnen. "An den Rändern" benötigen Sie also "* 10000" auf dem Weg nach innen und etwas "/ 10000" auf dem Weg nach draußen. Dies ist der von SQL Server von Microsoft verwendete Speichermechanismus (siehe http://msdn.microsoft.com/en-au/library/ms179882.aspx)
Das Schöne daran ist, dass Ihre gesamte Summierung mit (schneller) Ganzzahlarithmetik durchgeführt werden kann.
Die meisten Anwendungen, mit denen ich gearbeitet habe, verwenden decimal, um Geld darzustellen. Dies basiert auf der Annahme, dass sich die Anwendung niemals mit mehr als einer Währung befasst.
Diese Annahme kann auf einer anderen Annahme beruhen, dass die Anwendung niemals in anderen Ländern mit anderen Währungen verwendet wird. Ich habe Fälle gesehen, in denen sich das als falsch erwiesen hat.
Jetzt wird diese Annahme auf eine neue Art und Weise in Frage gestellt: Neue Währungen wie Bitcoin werden immer häufiger und sind für kein Land spezifisch. Es ist nicht unrealistisch, dass eine Anwendung, die nur in einem Land verwendet wird, möglicherweise noch mehrere Währungen unterstützen muss.
Einige Leute werden sagen, dass das Erstellen oder sogar Verwenden eines Typs nur für Geld "Vergoldung" ist oder zusätzliche Komplexität über die bekannten Anforderungen hinaus hinzufügt. Ich bin absolut anderer Meinung. Je allgegenwärtiger ein Konzept in Ihrer Domäne ist, desto wichtiger ist es, angemessene Anstrengungen zu unternehmen, um die richtige Abstraktion im Voraus zu verwenden. Wenn Sie die Komplexität sehen möchten, versuchen Sie, in einer Anwendung zu arbeiten, die früher verwendet wurde. decimalJetzt gibt es Currencyneben jeder decimalEigenschaft eine zusätzliche Eigenschaft.
Wenn Sie die falsche Abstraktion im Voraus verwenden, ist das spätere Ersetzen hundertmal mehr Arbeit. Dies bedeutet, dass möglicherweise Fehler in vorhandenen Code eingefügt werden, und das Beste daran ist, dass diese Fehler wahrscheinlich Geldbeträge, Transaktionen mit Geld oder einfach alles mit Geld betreffen.
Und es ist nicht so schwierig, etwas anderes als Dezimalzahl zu verwenden. Google "Nuget Money Type" und Sie werden sehen, dass zahlreiche Entwickler solche Abstraktionen erstellt haben (einschließlich mir). Es ist einfach. Es ist so einfach wie das Verwenden DateTimeeines Datums in einem string.
using System.ComponentModel.DataAnnotations;
[DataType(DataType.Currency)]
Antworten:
Wie dezimal beschrieben als:
Sie können eine Dezimalstelle wie folgt verwenden:
quelle
System.Decimal
Ich möchte auf diese hervorragende Antwort von zneak hinweisen, warum double nicht verwendet werden sollte.
quelle
Verwenden Sie das Money-Muster aus Patterns of Enterprise Application Architecture . Geben Sie den Betrag als Dezimalzahl und die Währung als Aufzählung an.
quelle
Money
Nuget hat einen toten Github-Link für die Projektsite, also ... keine Dokumente?Dezimal. Wenn Sie Double wählen, sind Sie offen für Rundungsfehler
quelle
double
kann Rundungsfehler verursachen, da Gleitkomma nicht alle Zahlen exakt darstellen kann (z. B. 0,01 hat keine exakte Darstellung im Gleitkomma).Decimal
, Auf der anderen Seite, ist für Zahlen genau . (Der KompromissDecimal
hat einen kleineren Bereich als Gleitkomma) Gleitkomma kann zu * unbeabsichtigten * Rundungsfehlern führen (z0.01+0.01 != 0.02
. B. ).Decimal
kann Ihnen Rundungsfehler geben, aber nur, wenn Sie danach gefragt haben (z. B.Math.Round(0.01+0.02)
gibt Null zurück)double
Skalierung und gegebenenfalls domänenspezifische Rundung verwendet und sorgfältig angewendet werden, kann dies vollkommen präzise sein. Wenn man in seiner Rundung schlampig ist,decimal
kann dies zu semantisch falschen Ergebnissen führen (z. B. wenn man mehrere Werte addiert, die auf den nächsten Cent gerundet werden sollen, aber nicht zuerst um sie herum). Das einzig gute darandecimal
ist, dass die Skalierung integriert ist.Dezimalzahl hat einen kleineren Bereich, aber eine höhere Präzision - damit Sie mit der Zeit nicht all diese Pfennige verlieren!
Alle Details hier:
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
quelle
Stimmen Sie dem Geldmuster zu: Der Umgang mit Währungen ist einfach zu umständlich, wenn Sie Dezimalstellen verwenden.
Wenn Sie eine Währungsklasse erstellen, können Sie dort die gesamte Geldlogik ablegen, einschließlich einer korrekten ToString () - Methode, einer besseren Kontrolle der Parsing-Werte und einer besseren Kontrolle der Divisionen.
Außerdem besteht bei einer Währungsklasse keine Möglichkeit, dass unbeabsichtigt Geld mit anderen Daten verwechselt wird.
quelle
Eine andere Option (insbesondere wenn Sie Ihre eigene Klasse rollen) besteht darin, ein int oder ein int64 zu verwenden und die unteren vier Ziffern (oder möglicherweise sogar 2) als "rechts vom Dezimalpunkt" zu kennzeichnen. "An den Rändern" benötigen Sie also "* 10000" auf dem Weg nach innen und etwas "/ 10000" auf dem Weg nach draußen. Dies ist der von SQL Server von Microsoft verwendete Speichermechanismus (siehe http://msdn.microsoft.com/en-au/library/ms179882.aspx)
Das Schöne daran ist, dass Ihre gesamte Summierung mit (schneller) Ganzzahlarithmetik durchgeführt werden kann.
quelle
Die meisten Anwendungen, mit denen ich gearbeitet habe, verwenden
decimal
, um Geld darzustellen. Dies basiert auf der Annahme, dass sich die Anwendung niemals mit mehr als einer Währung befasst.Diese Annahme kann auf einer anderen Annahme beruhen, dass die Anwendung niemals in anderen Ländern mit anderen Währungen verwendet wird. Ich habe Fälle gesehen, in denen sich das als falsch erwiesen hat.
Jetzt wird diese Annahme auf eine neue Art und Weise in Frage gestellt: Neue Währungen wie Bitcoin werden immer häufiger und sind für kein Land spezifisch. Es ist nicht unrealistisch, dass eine Anwendung, die nur in einem Land verwendet wird, möglicherweise noch mehrere Währungen unterstützen muss.
Einige Leute werden sagen, dass das Erstellen oder sogar Verwenden eines Typs nur für Geld "Vergoldung" ist oder zusätzliche Komplexität über die bekannten Anforderungen hinaus hinzufügt. Ich bin absolut anderer Meinung. Je allgegenwärtiger ein Konzept in Ihrer Domäne ist, desto wichtiger ist es, angemessene Anstrengungen zu unternehmen, um die richtige Abstraktion im Voraus zu verwenden. Wenn Sie die Komplexität sehen möchten, versuchen Sie, in einer Anwendung zu arbeiten, die früher verwendet wurde.
decimal
Jetzt gibt esCurrency
neben jederdecimal
Eigenschaft eine zusätzliche Eigenschaft.Wenn Sie die falsche Abstraktion im Voraus verwenden, ist das spätere Ersetzen hundertmal mehr Arbeit. Dies bedeutet, dass möglicherweise Fehler in vorhandenen Code eingefügt werden, und das Beste daran ist, dass diese Fehler wahrscheinlich Geldbeträge, Transaktionen mit Geld oder einfach alles mit Geld betreffen.
Und es ist nicht so schwierig, etwas anderes als Dezimalzahl zu verwenden. Google "Nuget Money Type" und Sie werden sehen, dass zahlreiche Entwickler solche Abstraktionen erstellt haben (einschließlich mir). Es ist einfach. Es ist so einfach wie das Verwenden
DateTime
eines Datums in einemstring
.quelle
Erstelle deine eigene Klasse. Dies scheint seltsam, aber ein .Net-Typ reicht nicht aus, um verschiedene Währungen abzudecken.
quelle