Je continue à voir des gens utiliser des doubles en C #. Je sais que j'ai lu quelque part que les doubles perdent parfois en précision. Ma question est la suivante: quand faut-il utiliser un double et quand dois-je utiliser un type décimal? Quel type convient aux calculs d'argent? (c.-à-d. supérieur à 100 millions de dollars)
Pour de l'argent, toujours décimal. C'est pourquoi il a été créé.
Si les nombres doivent additionner correctement ou équilibrer, utilisez décimal. Cela inclut tout stockage financier ou calculs, scores, ou autres chiffres que les gens pourraient faire à la main.
Si la valeur exacte des nombres n’a pas d’importance, utilisez double pour la vitesse. Cela inclut les graphiques, la physique ou d'autres calculs de sciences physiques pour lesquels il existe déjà un "nombre de chiffres significatifs".
Ma question est: quand faut-il utiliser un double et quand dois-je utiliser un type décimal?
decimal
lorsque vous travaillez avec des valeurs de l'ordre de 10 ^ (+/- 28) et que vous avez des attentes concernant le comportement basé sur des représentations en base 10 - essentiellement de l'argent.
double
lorsque vous avez besoin d'une précision relative (c.-à-d. Que perdre de la précision dans les derniers chiffres sur de grandes valeurs ne pose pas de problème) pour des grandeurs très différentes - double
couvertures plus de 10 ^ (+/- 300). Les calculs scientifiques sont le meilleur exemple ici.
quel type convient aux calculs d'argent?
décimal, décimal , décimal
N'accepter aucun substitut.
Le facteur le plus important est que double
, implémenté en tant que fraction binaire, ne peut pas représenter avec précision de nombreuses fractions decimal
(comme 0.1) et sa valeur globale. Le nombre de chiffres est plus petit car sa largeur est de 64 bits par rapport à 128 bits pour decimal
. Enfin, les applications financières doivent souvent suivre des règles spécifiques modes d’arrondissement (parfois prescrites par la loi). decimal
supporte ces ; double
ne le fait pas.
System.Single / float - 7 chiffres
System.Double / double - 15-16 chiffres
System.Decimal / décimal - 28-29 chiffres significatifs
La façon dont j'ai été piqué en utilisant le mauvais type (il y a quelques bonnes années) est avec de grandes quantités:
Vous manquez de 1 million pour un flottant.
Une valeur monétaire de 15 chiffres:
9 billions de dollars avec un double. Mais avec la division et les comparaisons, c'est plus compliqué (je ne suis certainement pas un expert en nombres flottants et irrationnels - voir le point de Marc ). Le mélange de nombres décimaux et de doubles cause des problèmes:
Une opération mathématique ou de comparaison qui utilise un nombre à virgule flottante peut ne pas donner le même résultat si un nombre décimal est utilisé, car le nombre à virgule flottante peut ne pas correspondre exactement au nombre décimal.
Quand devrais-je utiliser double au lieu de décimal? a des réponses similaires et plus approfondies.
Utiliser double
au lieu de decimal
pour les applications monétaires est une micro-optimisation - c'est la façon la plus simple de voir les choses.
Le nombre décimal correspond aux valeurs exactes. Double est pour les valeurs approximatives.
USD: $12,345.67 USD (Decimal)
CAD: $13,617.27 (Decimal)
Exchange Rate: 1.102932 (Double)
Pour de l'argent: decimal
. Cela coûte un peu plus de mémoire, mais n'a pas de problèmes d'arrondi comme double
parfois.
Certainement utilisez des types entiers pour vos calculs d'argent. Cela ne saurait être assez souligné, car à première vue, un type à virgule flottante peut sembler adéquat.
Voici un exemple dans le code python:
>>> amount = float(100.00) # one hundred dollars
>>> print amount
100.0
>>> new_amount = amount + 1
>>> print new_amount
101.0
>>> print new_amount - amount
>>> 1.0
semble assez normal.
Maintenant, essayez à nouveau avec 10 ^ 20 dollars zimbabwéens
>>> amount = float(1e20)
>>> print amount
1e+20
>>> new_amount = amount + 1
>>> print new_amount
1e+20
>>> print new_amount-amount
0.0
Comme vous pouvez le constater, le dollar a disparu.
Si vous utilisez le type entier, cela fonctionne bien:
>>> amount = int(1e20)
>>> print amount
100000000000000000000
>>> new_amount = amount + 1
>>> print new_amount
100000000000000000001
>>> print new_amount - amount
1
Je pense que la différence principale à côté de la largeur des bits est que le nombre décimal a la base de l’exposant 10 et le double 2.
http://software-product-development.blogspot.com/2008/07/net-double-vs-decimal.html