De plus, si vous utilisez des annotations de données, incluez using System.ComponentModel.DataAnnotations;... [DataType(DataType.Currency)]msdn.microsoft.com/en-us/library/…
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 devez expliquer en quoi ce lien est important. Une réponse doit être suffisamment bonne en elle-même, avec un lien comme référence ou détail supplémentaire. Voir stackoverflow.com/help/how-to-answer
TheRubberDuck
2
Ainsi, la réponse de longueur minimale peut contenir moins de caractères que le commentaire de longueur minimale - intéressant! Non pas que j'ai un problème avec la réponse concise / concise, surtout quand elle est également "profonde" en ce qu'elle est liée à une discussion plus approfondie.
B. Clay Shannon
3
Réponse incroyable, et je ne pense pas qu'elle ait besoin d'explications supplémentaires car elle répond complètement à la question. Le lien vers la documentation MSDN est un bonus en ce qui me concerne. Bravo!
trnelson
@Leee Treveil, à quoi ressemble l'argent (9.0098) signifie 4 caractères après le point
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é.
J'allais en fait le suggérer, mais je fais de la devise une classe afin de pouvoir définir un taux de change (par rapport à une "devise de base", souvent le dollar américain [que j'ai fixé pour avoir un taux de change de 1,00]).
Vous vous demandez si un tel type doit être une structure ou une classe. Une énumération décimale + an (int) lui donne 20 octets. Mon argent est encore en structure.
nawfal
Ce Moneynuget a un lien github mort pour le site du projet alors ... pas de documents?
George Mauer
Le problème est que si vous créez votre propre implémentation, vous devez trouver comment la conserver. Et l'ORM (EF) le plus populaire ne prend pas du tout en charge les types de données personnalisés. Par conséquent, on demande à quelqu'un d'aller très profondément dans les mauvaises herbes pour faire ce qui devrait être une chose assez simple.
George Mauer
25
Décimal. Si vous choisissez le double, vous vous exposez aux erreurs d'arrondi
@Jess doublepeut 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 Decimala 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). Decimalpeut vous donner des erreurs d'arrondi, mais uniquement lorsque vous l'avez demandé (par exemple, Math.Round(0.01+0.02)renvoie zéro)
Ian Boyd
2
@IanBoyd: La valeur "1,57 $" peut être représentée avec précision (double) 157. Si l'on utilise doubleet 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 decimalpeut 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 decimalest que la mise à l'échelle est intégrée.
supercat
1
@supercat, concernant ce commentaire "si l'on additionne plusieurs valeurs qui sont censées être arrondies au centime le plus proche, mais qui ne les entoure pas en premier", je ne vois pas comment un flotteur résoudrait cela. Il s'agit d'une erreur de l'utilisateur et n'a rien à voir avec les décimales à mon humble avis. j'obtiens le point mais je pense qu'il a été mal placé, principalement parce que IanBoyd l'a spécifié ... si vous le demandez.
sawe
16
decimal a une plage plus petite, mais une plus grande précision - donc vous ne perdez pas tous ces sous avec le temps!
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é decimalrepré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 decimalet maintenant il y a une Currencypropriété supplémentaire à côté de chaque decimalproprié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 DateTimeau lieu de stocker une date dans un fichier string.
using System.ComponentModel.DataAnnotations;
...[DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/…Réponses:
Comme il est décrit à la décimale comme:
Vous pouvez utiliser une décimale comme suit:
la source
System.Decimal
Je voudrais souligner cette excellente réponse de zneak sur la raison pour laquelle le double ne devrait pas être utilisé.
la source
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.
la source
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
la source
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 compromisDecimal
a une plage plus petite que la virgule flottante) La virgule flottante peut vous donner des erreurs d'arrondi * par inadvertance (par exemple0.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, celadecimal
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 chosedecimal
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:
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
la source
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.
la source
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 source
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 uneCurrency
propriété supplémentaire à côté de chaquedecimal
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 fichierstring
.la source
Créez votre propre classe. Cela semble étrange, mais un type .Net est insuffisant pour couvrir différentes devises.
la source