Je peux nommer trois avantages à utiliser double
(ou float
) au lieu de decimal
:
- Utilise moins de mémoire.
- Plus rapide car les opérations mathématiques en virgule flottante sont prises en charge nativement par les processeurs.
- Peut représenter une plus grande gamme de nombres.
Mais ces avantages semblent s'appliquer uniquement aux opérations de calcul intensif, comme celles que l'on trouve dans les logiciels de modélisation. Bien sûr, les doubles ne doivent pas être utilisés lorsque la précision est requise, comme les calculs financiers. Y a-t-il donc des raisons pratiques de choisir double
(ou float
) plutôt que decimal
dans les applications "normales"?
Modifié pour ajouter: Merci pour toutes les bonnes réponses, j'ai appris d'eux.
Une autre question: quelques personnes ont fait valoir que les doubles peuvent représenter plus précisément les nombres réels. Une fois déclarés, je pense qu'ils les représentent généralement plus précisément. Mais est-ce une affirmation vraie que la précision peut diminuer (parfois de manière significative) lorsque des opérations en virgule flottante sont effectuées?
Réponses:
Je pense que vous avez assez bien résumé les avantages. Il vous manque cependant un point. Le
decimal
type est seulement plus précis pour représenter les nombres de base 10 (par exemple ceux utilisés dans les calculs monétaires / financiers). En général, ledouble
type va offrir au moins une grande précision (quelqu'un me corrige si je me trompe) et une vitesse nettement supérieure pour les nombres réels arbitraires. La conclusion simple est la suivante: lorsque vous envisagez de l'utiliser, utilisez-le toujours àdouble
moins que vous n'ayez besoin de labase 10
précision qu'ildecimal
offre.Éditer:
En ce qui concerne votre question supplémentaire sur la diminution de la précision des nombres à virgule flottante après les opérations, il s'agit d'un problème légèrement plus subtil. En effet, la précision (j'utilise le terme de manière interchangeable pour la précision ici) diminuera régulièrement après chaque opération. Cela est dû à deux raisons:
Dans tous les cas, si vous souhaitez comparer deux nombres à virgule flottante qui devraient en théorie être équivalents (mais qui ont été déterminés à l'aide de calculs différents), vous devez autoriser un certain degré de tolérance (la quantité varie, mais est généralement très petite) .
Pour un aperçu plus détaillé des cas particuliers où des erreurs de précision peuvent être introduites, consultez la section Précision de l'article Wikipedia . Enfin, si vous voulez une discussion sérieuse (et mathématique) sur les nombres / opérations à virgule flottante au niveau de la machine, essayez de lire l'article souvent cité Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante .
la source
double
. Les ordinateurs modernes imprimeront toujours la valeur correcte, mais uniquement parce qu'ils «devinent» le résultat - pas parce qu'il est vraiment exprimé correctement.Decimal
type a une précision de 93 bits dans la mantisse, contre environ 52 pourdouble
. Je souhaite que Microsoft prenne en charge le format IEEE 80 bits, même s'il doit être complété à 16 octets; il aurait permis une plage plus largedouble
ouDecimal
, bien meilleureDecimal
, que la prise en charge des opérations transcendantales (par exemple sin (x), log (x), etc.), et une précision qui, bien que pas aussi bonne queDecimal
serait bien meilleure quedouble
.Vous semblez avoir les avantages d'utiliser un type à virgule flottante. J'ai tendance à concevoir des décimales dans tous les cas, et je compte sur un profileur pour me faire savoir si les opérations sur les décimales provoquent des goulots d'étranglement ou des ralentissements. Dans ces cas, je vais "down cast" pour doubler ou flotter, mais seulement le faire en interne, et essayer soigneusement de gérer la perte de précision en limitant le nombre de chiffres significatifs dans l'opération mathématique effectuée.
En général, si votre valeur est transitoire (non réutilisée), vous pouvez utiliser un type à virgule flottante en toute sécurité. Le vrai problème avec les types à virgule flottante est les trois scénarios suivants.
123456789.1 * .000000000000000987654321
)ÉDITER
Selon la documentation de référence sur les décimales C # :
Donc, pour clarifier ma déclaration ci-dessus:
Je n'ai jamais travaillé que dans des industries où les décimales sont favorables. Si vous travaillez sur des moteurs phsyics ou graphiques, il est probablement beaucoup plus avantageux de concevoir un type à virgule flottante (float ou double).
Décimal n'est pas infiniment précis (il est impossible de représenter une précision infinie pour les non-intégrales dans un type de données primitif), mais il est beaucoup plus précis que double:
EDIT 2
En réponse au commentaire de Konrad Rudolph , l'élément # 1 (ci-dessus) est définitivement correct. L'agrégation de l'imprécision aggrave en effet. Voir le code ci-dessous pour un exemple:
Cela génère les éléments suivants:
Comme vous pouvez le voir, même si nous ajoutons à partir de la même constante de source, les résultats du double sont moins précis (bien que probablement arrondis correctement), et le flottant est beaucoup moins précis, au point où il a été réduit à seulement deux chiffres significatifs.
la source
Single: 667660.400000000000
tandis que la valeur décimale a donnéDecimal: 666666.7000000000
. La valeur flottante est légèrement inférieure à mille sur la valeur correcte.Utilisez la décimale pour les valeurs de base 10, par exemple les calculs financiers, comme d'autres l'ont suggéré.
Mais le double est généralement plus précis pour les valeurs calculées arbitrairement.
Par exemple, si vous souhaitez calculer le poids de chaque ligne d'un portefeuille, utilisez le double car le résultat totalisera presque 100%.
Dans l'exemple suivant, doubleResult est plus proche de 1 que decimalResult:
Reprenons donc l'exemple d'un portfolio:
La valeur marchande de chaque ligne du portefeuille est une valeur monétaire et serait probablement mieux représentée sous forme décimale.
Le poids de chaque ligne du portefeuille (= Market Value / SUM (Market Value)) est généralement mieux représenté par le double.
la source
Utilisez un double ou un flotteur lorsque vous n'avez pas besoin de précision, par exemple, dans un jeu de plateforme que j'ai écrit, j'ai utilisé un flotteur pour stocker les vitesses des joueurs. Évidemment, je n'ai pas besoin de super précision ici car je finis par me tourner vers un Int pour dessiner sur l'écran.
la source
Dans certains comptes, envisagez la possibilité d'utiliser des types intégraux à la place ou conjointement. Par exemple, supposons que les règles sous lesquelles vous opérez exigent que chaque résultat de calcul soit reporté avec au moins 6 décimales et le résultat final sera arrondi au centime le plus proche.
Un calcul de 1/6 de 100 $ donne 16,6666666666666666 ..., donc la valeur reportée dans une feuille de calcul sera 16,666667 $. Les doubles et les décimales devraient produire ce résultat avec précision à 6 décimales. Cependant, nous pouvons éviter toute erreur cumulative en reportant le résultat sous la forme d'un entier 16666667. Chaque calcul ultérieur peut être effectué avec la même précision et reporté de manière similaire. Poursuivant l'exemple, je calcule la taxe de vente du Texas sur ce montant (16666667 * .0825 = 1375000). Ajouter les deux (c'est une courte feuille de calcul) 1666667 + 1375000 = 18041667. Remettre le point décimal en arrière nous donne 18.041667, ou 18.04 $.
Bien que ce court exemple ne produise pas d'erreur cumulative en utilisant le double ou le décimal, il est assez facile de montrer des cas où le simple calcul du double ou du décimal et le report accumuleraient une erreur significative. Si les règles sous lesquelles vous opérez nécessitent un nombre limité de décimales, stockez chaque valeur sous forme d'entier en multipliant par 10 ^ (nombre de décimales requis), puis en divisant par 10 ^ (nombre de décimales requis) pour obtenir le nombre réel La valeur évitera toute erreur cumulative.
Dans les situations où des fractions de cent ne se produisent pas (par exemple, un distributeur automatique), il n'y a aucune raison d'utiliser des types non intégraux. Pensez-y simplement comme comptant des sous, pas des dollars. J'ai vu du code où chaque calcul n'impliquait que des sous entiers, mais l'utilisation du double a conduit à des erreurs! Entier uniquement les mathématiques ont supprimé le problème. Donc, ma réponse non conventionnelle est, lorsque cela est possible, de renoncer à la fois au double et à la décimale.
la source
Si vous devez interagir binaire avec d'autres langages ou plates-formes, vous devrez peut-être utiliser float ou double, qui sont standardisés.
la source
Remarque: ce message est basé sur des informations sur les capacités du type décimal de http://csharpindepth.com/Articles/General/Decimal.aspx et sur ma propre interprétation de ce que cela signifie. Je suppose que Double est une double précision IEEE normale.
Note2: les plus petits et les plus grands dans ce post se réfèrent à l'ampleur du nombre.
Avantages de "décimal".
Contre décimal
Mon opinion est que vous devez utiliser par défaut "décimal" pour le travail de l'argent et d'autres cas où la correspondance exacte du calcul humain est importante et que vous devez utiliser le double comme choix par défaut le reste du temps.
la source
Cela dépend de ce dont vous avez besoin.
Parce que float et double sont des types de données binaires que vous avez un certain difficultés et des erreurs dans la manière dont les nombres sont arrondis. Autrement dit, tous les nombres réels n'ont pas une représentation précise en types doubles
Heureusement, C # prend également en charge ce que l'on appelle l'arithmétique décimale à virgule flottante, où les nombres sont représentés via le système numérique décimal plutôt que le système binaire. Ainsi, l'arithmétique décimale à virgule flottante ne perd pas sa précision lors du stockage et du traitement des nombres à virgule flottante. Cela le rend extrêmement adapté aux calculs nécessitant un haut niveau de précision.
la source
Utilisez des virgules flottantes si vous appréciez les performances par rapport à l'exactitude.
la source
Choisissez le type en fonction de votre application. Si vous avez besoin de précision comme en analyse financière, vous avez répondu à votre question. Mais si votre demande peut se régler avec une estimation, vous êtes d'accord avec le double.
Votre application a-t-elle besoin d'un calcul rapide ou aura-t-il tout le temps du monde pour vous donner une réponse? Cela dépend vraiment du type d'application.
Graphique affamé? flotter ou double suffit. Analyse des données financières, météore frappant une planète de précision? Celles-ci auraient besoin d'un peu de précision :)
la source
Decimal a des octets plus larges, le double est nativement pris en charge par le CPU. Decimal est en base 10, donc une conversion décimale en double se produit pendant le calcul d'une décimale.
Gardez à l'esprit que .NET CLR ne prend en charge que Math.Pow (double, double). Decimal n'est pas pris en charge.
.NET Framework 4
la source
Une valeur double sera sérialisée en notation scientifique par défaut si cette notation est plus courte que l'affichage décimal. (par exemple .00000003 sera 3e-8) Les valeurs décimales ne seront jamais sérialisées en notation scientifique. Lors de la sérialisation pour la consommation par une partie externe, cela peut être une considération.
la source