web-dev-qa-db-fra.com

décimal vs double! - Lequel dois-je utiliser et quand?

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)

836
Soni Ali

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".

990
David

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). decimalsupporte ces ; double ne le fait pas.

170
Michael Borgwardt

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:

  • £ 520,532.52 - 8 chiffres
  • 1.323.523,12 £ - 9 chiffres

Vous manquez de 1 million pour un flottant.

Une valeur monétaire de 15 chiffres:

  • 1.234.567.890.123.45 £

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.

38
Chris S

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)
35
Ian Boyd

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.

27
Clement Herreman

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
9
Otto Allmendinger

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

5
Honzajscz