Différence entre décimal, float et double dans .NET?
Quelle est la différence entre decimal
, float
et double
dans .NET?
Quand quelqu'un utilise un de ces?
- article intéressant zetcode.com/lang/csharp/datatypes
- Connexes: sandbox.mc.edu/~bennet/cs110/flt/dtof.html
Vous devez vous connecter pour publier un commentaire.
float
etdouble
sont flottant binaire types de points de. En d'autres termes, ils représentent un nombre comme ceci:Le nombre binaire en nombre et l'emplacement des binaires point sont à la fois codées au sein de la valeur.
decimal
est un flottant décimal type de point de. En d'autres termes, ils représentent un nombre comme ceci:Encore une fois, le nombre et l'emplacement de la décimal point sont à la fois codées au sein de la valeur – c'est ce qui rend
decimal
encore un type à virgule flottante au lieu d'un point fixe de type.La chose importante à noter est que les humains sont utilisés pour représenter des nombres non entiers dans une forme décimale, et s'attendre à des résultats exacts en décimal représentations de, pas tous les nombres décimaux sont exactement représentable en virgule flottante binaire – 0.1, par exemple – ainsi, si vous utilisez un fichier binaire à virgule flottante valeur que vous aurez réellement obtenir une approximation de 0.1. Vous aurez toujours des approximations lors de l'utilisation d'une virgule flottante – le résultat de la division de 1 par 3 ne peut pas être représentée exactement, par exemple.
Que pour ce à utiliser lors de l':
Pour les valeurs qui sont "naturellement exacte décimales" c'est bien d'utiliser
decimal
. C'est généralement adapté pour tous les concepts inventés par l'homme: les valeurs financières sont l'exemple le plus évident, mais il y a aussi les autres. Considérer le score donné à des plongeurs ou du patin à glace, par exemple.Pour les valeurs qui sont plus que des artefacts de la nature qui ne peut pas vraiment être mesurée exactement de toute façon,
float
/double
sont plus appropriés. Par exemple, les données scientifiques seraient habituellement représenté sous cette forme. Ici, les valeurs d'origine ne seront pas "des décimales exactes" pour commencer, de sorte qu'il n'est pas important pour les résultats attendus pour maintenir la "virgule de précision". Flottante binaire types de points sont beaucoup plus rapides à utiliser que les décimales.float
/double
l'habitude de ne pas représenter les nombres comme101.101110
, normalement, il est représenté comme quelque chose comme1101010 * 2^(01010010)
- un exposantfloat
est un alias C# mot-clé et n'est pas un .Type de Net. c'estSystem.Single
..single
etdouble
sont flottante binaire types de points.System.Double
,decimal
est un alias pourSystem.Double
etstring
est un alias pourSystem.String
.floats
/doubles
nous obtenons:Console.WriteLine(0.1 + 0.2 == 0.3); // false
. Si je comprends bien, ce n'est pas l'égalité en raison de la conversion de la notation décimale nous utilisons dans le code de la notation binaire utilisé dans la mémoire. On peut le faire cependant dans l'autre sens? Initialiserdecimal
variables avec la notation binaire en code et ensuite obtenir un semblable incompatibilité?La précision est la principale différence.
Flotteur - 7 chiffres (32 bits)
Double-15-16 chiffres (64 bits)
Décimal -28-29 chiffres significatifs (128 bits)
Décimales ont beaucoup plus de précision et sont généralement utilisés dans les applications financières qui exigent un degré élevé de précision. Les décimales sont beaucoup plus lents (jusqu'à 20X fois dans certains tests) que d'un lit double ou float.
Des décimales et des Flotteurs/Double ne peut pas être comparé sans exprimés alors que des Flotteurs et des Doubles peut. Décimales également permettre l'encodage ou les zéros à droite.
Résultat :
Example: 0.1 = 0.099999.... in float but in decimal it is 0.l, that is infinite precision. If you were to use 128 bits precision like in floats, you would get 0.999999....(upto 29 digits) but that is still not precise as decimal 0.1
Try this: represent 0.3333 in floating point, you will end up with 0.3332999998..., this is not 0.3333 (you see the error). Now represent this in decimal it is 0.3333 (exactly as it is, no error - 100% accurate).
0.1
-- qui est rarement le cas dans le monde réel! Aucun stockage finie format amalgame entre un nombre infini de valeurs possibles pour un nombre fini de configurations de bits. Par exemple,float
sera un amalgame entre les0.1
et0.1 + 1e-8
, tandis quedecimal
sera un amalgame entre les0.1
et0.1 + 1e-29
. Bien sûr, à l'intérieur d'une plage donnée, certaines valeurs peuvent être représentées dans un format quelconque avec zéro perte de précision (p. ex.float
pouvez stocker tous les entiers jusqu'à 1.6e7 avec zéro perte de précision), mais c'est toujours pas infini précision.if(0.1 = 0.1)
cette condition n'est vraie lorsque nous pensons que cela doit être vrai. En décimal, il sera TOUJOURS vrai parce que de 0,1 sera de 0,1 et rien d'autre. Par exemple, il ne sera pas 0.99999999999999999999999999999.0.1
est ce n'est pas une valeur spéciale! La seule chose qui rend0.1
"mieux" que0.10000001
est parce que les êtres humains comme la base 10. Et même avec unfloat
valeur, si vous initialisez les deux valeurs avec0.1
de la même façon, ils seront tous deux la même valeur. C'est juste que cette valeur ne sera pas exactement0.1
-- il sera la valeur la plus proche de0.1
qui peut être représentée exactement comme unfloat
. Bien sûr, avec les binaires de flotteurs,(1.0 / 10) * 10 != 1.0
, mais avec décimale flotteurs,(1.0 / 3) * 3 != 1.0
soit. Ni est parfaitement précis.double a = 0.1; double b = 0.1;
puisa == b
sera vrai. C'est juste quea
etb
sera deux ce n'est pas exactement égale0.1
. En C#, si vous nedecimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;
puisa == b
sera également vrai. Mais dans ce cas, ni dea
nib
sera exactement l'égalité des1/3
-- ils à la fois l'égalité0.3333...
. Dans deux cas, une certaine exactitude est perdu à cause de la représentation. Vous obstinément de dire quedecimal
a "infini", de précision, qui est false.0.1 == 0.1
.decimal
. Beaucoup de nombres rencontrés dans la vie quotidienne ont cette propriété (parce que le sont discrètes, pas en continu, mesures), mais beaucoup d'autres ne le font pas. Le type de données approprié pour n'importe quel but dépend toujours de l'effet. S'il vous plaît ne pas abuser de tout ce que je veux dire ici que ce qui implique que n'importe qui devrait toujours utiliser des flotteurs -- je suis simplement en disant qu'on ne devrait pas aveuglément toujours utiliserdecimal
s à la place.(0.1f == 1f/10)
et(0.1m == 1m/10)
. La première permettra d'évaluer à faux tandis que le second permettra d'évaluer de vrai, même si les deux doivent avoir la valeur true. Cela est dû au fait que le flotteur ne peut pas exactement de stocker la valeur de 0,1.1f/10
estfloat
. Vous dites que les compilateurs ne sont pas requis pour arrondir le résultat de la division la plus prochefloat
avant d'effectuer la comparaison? Je considère comme un peu cassé le fait que l'on est autorisé à comparer directement unfloat
à autre chose, ou undouble
à rien d'autre que le 32 bits ou plus petit des entiers [je pense à un casting devrait être nécessaire], mais je considère sévèrement un compilateur qui a exécuté ce qui était par les règles de la langue d'un flotteur/float comparaison, comme s'il s'agissait d'un float/double comparaison.double
et généralement permettre implicite down-conversion àfloat
, mais ne permettraient pas d'établir des comparaisons directes entre les versions 32 bits et 64 bits des valeurs. Je postulons que, tandis que le C# n'aura aucun scrupule à propos dedouble d1=f1*f2;
il serait rare que le programmeur de l'intention qued1
pourrait tenir unfloat
-résultat de précision.)float
etdouble
pouvez exactement représente les fractions de la formep/q
oùq
est une puissance de 2. E. g. 0.5, 3.25, 1/256, etc.decimal
cependant pouvez exactement représente les fractions de la formep/q
oùq
est une puissance de 10 (dix). Voir cette réponse. S'il est exact quedecimal
a plus de chiffres significatifs, il est trompeur de laisser à la représentation est fondamentalement différente de cellefloat
etdouble
qui prêtedecimal
à la précision des décimales dans les calculs.0.0000000037252902984619140625m
. Mais vous ne pouvez pas; diviser par 2 donne0.0000000018626451492309570312m
au lieu de0.00000000186264514923095703125
decimal
mais pas commedouble
, il y a certaines valeurs qui peuvent être représentées exactement commedouble
mais pasdecimal
. Considérons la fraction1 / 2^31
. Ledecimal
représentation est tronqué, alors que ledouble
représentation est exacte. L' .NET représentation de chaîne de ladouble
n'est pas exacte, mais dans la mémoire de bits de la représentation est exacte. Jon Skeet a une classe qui permettra de convertir n'importe quel double à la décimale exacte représentation sous forme de chaîne, qui peut être assez long: csharpindepth.com/Articles/General/FloatingPoint.aspxLa structure Decimal est strictement axé sur les calculs financiers nécessitant de la précision, qui sont relativement intolérant de l'arrondissement. Les décimales ne sont pas suffisantes pour les applications scientifiques, cependant, pour plusieurs raisons:
Pour plus d'informations, voir:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5
float
7 chiffres de précisiondouble
a environ une précision de 15 chiffresdecimal
a environ 28 chiffres de précisionSi vous avez besoin de plus de précision, utilisez le double au lieu de flotter.
Dans les Processeurs modernes les deux types de données ont presque les mêmes performances. Le seul avantage de l'aide du flotteur est qu'ils prennent moins d'espace. Pratiquement questions uniquement si vous avez beaucoup d'entre eux.
J'ai trouvé ce qui est intéressant. Ce Que Tout Informaticien Devez Savoir À Propos De L'Arithmétique À Virgule Flottante
double
bon dans les applications de comptabilité dans ces cas (et en gros les seuls cas) où aucun type entier de plus de 32 bits est disponible, et ledouble
a été utilisé comme s'il s'agissait d'un 53 bits de type entier (par exemple, avoir un nombre entier de pièces de monnaie, ou un nombre entier de centièmes de pour cent). Pas beaucoup d'utilisation pour de telles choses de nos jours, mais de nombreuses langues, a acquis la capacité à utiliser la double-precision floating-point des valeurs à long avant qu'ils acquis de 64 bits (ou, dans certains cas, même en 32 bits!) math entier.Real
pourrait IIRC représentent des valeurs jusqu'à 1,8 E+19 avec l'unité de précision. Je pense qu'il serait beaucoup plus saine pour une application de comptabilité à l'utilisationReal
pour représenter un nombre entier de pièces de monnaie de...double
type qui avait la précision de l'unité jusqu'à 9E15. Si l'on a besoin de stocker des nombres entiers qui sont plus grands que le plus grand disponible de type entier, à l'aide dedouble
est apte à être plus simple et plus efficace que d'essayer de fudge multi-mathématiques de précision, d'autant plus que les processeurs ont des instructions pour exécuter 16x16->32 ou...Je ne vais pas réitérer des tonnes de bons (et mauvais) informations déjà répondu dans d'autres réponses et les commentaires, mais je vais répondre à votre question de suivi avec une astuce:
Décimal pour compté valeurs
Utiliser float/double pour mesurée valeurs
Quelques exemples:
de l'argent (nous ne compter l'argent ou de la mesure de l'argent?)
distance (nous ne décompte de la distance ou de mesurer la distance? *)
scores (ne nous compter les scores ou de mesurer les scores?)
Nous comptons toujours de l'argent et ne devrait jamais mesurer. Nous avons l'habitude de mesurer la distance. Nous comptons souvent scores.
* Dans certains cas, ce que j'appellerais distance nominale, on peut en effet vouloir "comte" de distance. Par exemple, peut-être que nous avons affaire avec des pays les signes qui montrent les distances vers les villes, et nous savons que ces distances ne jamais avoir plus d'un chiffre décimal (xxx.x km).
Personne n'a mentionné que
Je veux dire
jette OverflowException.
Mais ceux-ci n':
&
float.MaxValue+1 == float.MaxValue
, tout commedecimal.MaxValue+0.1D == decimal.MaxValue
. Peut-être que vous avez voulu dire quelque chose commefloat.MaxValue*2
?System.Decimal
déclenche une exception juste avant qu'il devient impossible de distinguer des unités entières, mais si une application est censée être traiter avec, par exemple, des dollars et des cents, qui pourrait être trop tard.Entiers, comme cela a été mentionné, sont des nombres entiers. Ils ne peuvent pas stocker le point de quelque chose, comme .7, .42, et .007. Si vous avez besoin de stocker des nombres qui ne sont pas des nombres entiers, vous avez besoin d'un autre type de variable. Vous pouvez utiliser le type double ou le type float. Vous définissez ces types de variables jusqu'exactement de la même manière: au lieu d'utiliser le mot
int
, vous tapezdouble
oufloat
. Comme ceci:(
float
est l'abréviation de "virgule flottante", et signifie seulement d'un nombre avec un point de quelque chose sur la fin.)La différence entre les deux réside dans la taille des nombres qu'ils peuvent tenir. Pour
float
, vous pouvez avoir jusqu'à 7 chiffres de votre numéro. Pourdouble
s, vous pouvez avoir jusqu'à 16 chiffres. Pour être plus précis, voici la taille officielle:float
est un nombre de 32 bits, etdouble
est un nombre de 64 bits.Double cliquez sur le bouton nouveau pour obtenir le code. Ajouter les trois lignes suivantes à votre code du bouton:
Arrêter votre programme et revenir à la fenêtre de codage. Modifier cette ligne:
Exécuter votre programme et cliquez sur votre bouton double. La boîte de message affiche correctement le nombre. Ajouter un autre numéro sur la fin, cependant, et C# sera de nouveau en rond vers le haut ou vers le bas. La morale est que si vous voulez de la précision, être prudent de l'arrondissement!
decimal
par zéro (CS0020), et le même est vrai de l'ensemble des littéraux. Toutefois, si l'exécution, la valeur décimale est divisé par zéro, vous aurez une exception et non une erreur de compilation.Cela a été un sujet intéressant pour moi, car aujourd'hui, nous avons juste eu un petit méchant bug, concernant
decimal
d'avoir moins de précision qu'unfloat
.Dans notre code C#, nous sommes à la lecture des valeurs numériques à partir d'une feuille de calcul Excel, en les convertissant en un
decimal
, puis l'envoi de cedecimal
retour à un Service pour enregistrer dans un SQL Server base de données.Maintenant, pour presque tous les de nos valeurs Excel, cela a fonctionné à merveille. Mais pour certains, de très petites valeurs Excel, à l'aide de
decimal.TryParse
perdu totalement la valeur. Un exemple estcellValue = 0.00006317592
Décimal.TryParse(cellValue.ToString(), valeur); //serait de retour 0
La solution, bizarrement, était de convertir les valeurs Excel dans un
double
d'abord, et ensuite dans undecimal
:Même si
double
a moins de précision qu'undecimal
, c'est en fait assurée petit nombre serait encore reconnu. Pour une raison quelconque,double.TryParse
été réellement en mesure de récupérer ces petits nombres, alors quedecimal.TryParse
serait de les mettre à zéro.Bizarre. Très bizarre.
decimal.Parse("0.00006317592")
fonctionne, vous avez quelque chose d'autre se passe. - Peut-être la notation scientifique?decimal
est en fait stockée dans le format décimal (par opposition à la base 2; afin de ne pas perdre ou rond chiffres en raison de la conversion entre les deux systèmes numériques); en outre,decimal
n'a pas de notion de valeurs spéciales telles que NaN, -0, ∞ ou -∞.Pour des applications telles que des jeux et des systèmes embarqués où la mémoire et les performances sont à la fois critique, le float est généralement le type numérique de choix car il est plus rapide et la moitié de la taille d'un double. Les entiers utilisés pour être l'arme de choix, mais de performance en virgule flottante a dépassé entier dans les processeurs modernes. Virgule est juste!
De la Virgule, Double et Float types de variables sont différentes dans la manière dont ils stocker les valeurs. La précision est la principale différence où float est une simple précision (32 bits) de données à virgule flottante double est double précision (64 bits) virgule flottante et le type de données décimal est une virgule flottante 128 bits type de données.
Float 32 bits (7 chiffres)
Double - 64 bits (de 15 à 16 chiffres)
Décimal - 128 bits (28-29 chiffres significatifs)
Plus sur...la différence entre Décimal, Float et Double
Le problème avec tous ces types est qu'une certaine imprécision subsiste
ET que ce problème peut se produire avec de petits nombres décimaux comme dans l'exemple suivant
Question: quelle est la valeur de soufflerie variable contient-il ?
Réponse: Sur un ordinateur 32 bits ventilateur contient de VRAI !!!
Si je remplace le Double en Décimal, ventilateur contient de FAUX qui est la bonne réponse.
En double, le problème est que fMean-fDelta = 1.09999999999 qui est plus faible que 1.1.
Attention: je pense que le même problème existe bel et bien pour d'autres nombre, parce que la Décimale est un double avec plus de précision et de la précision a toujours une limite.
En fait, Double, Float et Décimal correspondent à BINAIRE décimal en COBOL !
Il est regrettable que d'autres types numériques mis en œuvre dans le COBOL n'existent pas .Net. Pour ceux qui ne connaissent pas COBOL, il existe en COBOL suivant type numérique
En termes simples:
Vous pouvez en lire plus ici, Flotteur, Double, et Décimal.
Decimal
adapté pour les applications financières, et c'est le principal critère à utiliser au moment de décider entreDecimal
etDouble
. Il est rare queDouble
précision n'est pas suffisante pour les applications scientifiques, par exemple (etDecimal
est souvent inadaptés pour les applications scientifiques, en raison de sa portée limitée).La principale différence entre chacun de ces est la précision.
float
est un32-bit
nombre,double
est un64-bit
nombre etdecimal
est un128-bit
nombre.