Quel est le meilleur type de données à utiliser pour de l'argent en C #?
using System.ComponentModel.DataAnnotations;
... [DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/…
Quel est le meilleur type de données à utiliser pour de l'argent en C #?
using System.ComponentModel.DataAnnotations;
... [DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/…
Réponses:
Comme il est décrit à la décimale comme:
Le mot clé décimal indique un type de données 128 bits. Comparé aux types à virgule flottante, le type décimal a plus de précision et une plage plus petite, ce qui le rend approprié pour les calculs financiers et monétaires .
Vous pouvez utiliser une décimale comme suit:
decimal myMoney = 300.5m;
Le type de valeur décimale représente des nombres décimaux allant de positif 79.228.162.514.264.337.593.543.950.335 à négatif 79.228.162.514.264.337.593.543.950.335. Le type de valeur décimale convient aux calculs financiers nécessitant un grand nombre de chiffres entiers et fractionnaires significatifs et aucune erreur d'arrondi. Le type décimal n'élimine pas la nécessité d'arrondir. Au contraire, il minimise les erreurs dues à l'arrondissement.
Je voudrais souligner cette excellente réponse de zneak sur la raison pour laquelle le double ne devrait pas être utilisé.
Utilisez le modèle Money de Patterns of Enterprise Application Architecture ; spécifiez le montant sous forme décimale et la devise sous forme d'énumération.
Money
nuget a un lien github mort pour le site du projet alors ... pas de documents?
Décimal. Si vous choisissez le double, vous vous exposez aux erreurs d'arrondi
double
peut introduire des erreurs d'arrondi car la virgule flottante ne peut pas représenter exactement tous les nombres (par exemple, 0,01 n'a pas de représentation exacte en virgule flottante). Decimal
, D'autre part, ne représentent des nombres exactement . (Le compromis Decimal
a une plage plus petite que la virgule flottante) La virgule flottante peut vous donner des erreurs d'arrondi * par inadvertance (par exemple 0.01+0.01 != 0.02
). Decimal
peut vous donner des erreurs d'arrondi, mais uniquement lorsque vous l'avez demandé (par exemple, Math.Round(0.01+0.02)
renvoie zéro)
double
et applique soigneusement l'échelle et l'arrondi spécifique au domaine le cas échéant, cela peut être parfaitement précis. Si l'on est bâclé dans son arrondi, cela decimal
peut donner des résultats sémantiquement incorrects (par exemple, si l'on additionne plusieurs valeurs qui sont censées être arrondies au centime le plus proche, mais qui ne les entourent pas en premier). La seule bonne chose decimal
est que la mise à l'échelle est intégrée.
decimal a une plage plus petite, mais une plus grande précision - donc vous ne perdez pas tous ces sous avec le temps!
Tous les détails ici:
Acceptez le modèle Money: la gestion des devises est tout simplement trop lourde lorsque vous utilisez des décimales.
Si vous créez une classe Currency, vous pouvez alors y mettre toute la logique relative à l'argent, y compris une méthode ToString () correcte, plus de contrôle des valeurs d'analyse et un meilleur contrôle des divisions.
De plus, avec une classe Currency, il n'y a aucune chance de mélanger involontairement de l'argent avec d'autres données.
Une autre option (surtout si vous faites rouler votre propre classe) consiste à utiliser un int ou un int64, et à désigner les quatre chiffres inférieurs (ou peut-être même 2) comme «à droite de la virgule décimale». Donc, "sur les bords", vous aurez besoin de "* 10000" à l'entrée et de "/ 10000" à la sortie. Il s'agit du mécanisme de stockage utilisé par SQL Server de Microsoft, voir http://msdn.microsoft.com/en-au/library/ms179882.aspx
La particularité est que toute votre sommation peut être faite en utilisant l'arithmétique d'entier (rapide).
La plupart des applications avec lesquelles j'ai travaillé decimal
représentent l'argent. Ceci est basé sur l'hypothèse que l'application ne sera jamais concernée par plus d'une devise.
Cette hypothèse peut être basée sur une autre hypothèse, selon laquelle l'application ne sera jamais utilisée dans d'autres pays avec des devises différentes. J'ai vu des cas où cela s'est avéré faux.
Maintenant, cette hypothèse est remise en question d'une nouvelle manière: les nouvelles devises telles que le Bitcoin sont de plus en plus courantes et ne sont spécifiques à aucun pays. Il n'est pas irréaliste qu'une application utilisée dans un seul pays doive encore prendre en charge plusieurs devises.
Certaines personnes diront que créer ou même utiliser un type juste pour de l'argent est un "placage à l'or" ou ajouter une complexité supplémentaire au-delà des exigences connues. Je suis fortement en désaccord. Plus un concept est omniprésent dans votre domaine, plus il est important de faire un effort raisonnable pour utiliser l'abstraction correcte à l'avance. Si vous voulez voir la complexité, essayez de travailler dans une application qui utilisait autrefois decimal
et maintenant il y a une Currency
propriété supplémentaire à côté de chaque decimal
propriété.
Si vous utilisez la mauvaise abstraction à l'avance, le remplacer plus tard sera cent fois plus de travail. Cela signifie potentiellement introduire des défauts dans le code existant, et la meilleure partie est que ces défauts impliqueront probablement des sommes d'argent, des transactions avec de l'argent ou tout simplement quelque chose avec de l'argent.
Et ce n'est pas si difficile d'utiliser autre chose que décimal. Google "nuget money type" et vous verrez que de nombreux développeurs ont créé de telles abstractions (y compris moi.) C'est facile. C'est aussi simple que d'utiliser DateTime
au lieu de stocker une date dans un fichier string
.
Créez votre propre classe. Cela semble étrange, mais un type .Net est insuffisant pour couvrir différentes devises.