Quelle est la différence entre decimal
, float
et double
dans .NET?
Quand quelqu'un en utiliserait-il un?
.net
floating-point
double
decimal
PC Luddite
la source
la source
Réponses:
float
etdouble
sont des types de points binaires flottants . En d'autres termes, ils représentent un nombre comme celui-ci:Le nombre binaire et l'emplacement du point binaire sont tous deux codés dans la valeur.
decimal
est une variable décimale type de point . En d'autres termes, ils représentent un nombre comme celui-ci:Encore une fois, le nombre et l'emplacement du point décimal sont tous deux codés dans la valeur - c'est ce qui fait
decimal
toujours un type à virgule flottante au lieu d'un type à point fixe.La chose importante à noter est que les humains sont habitués à représenter des nombres non entiers sous une forme décimale et attendent des résultats exacts dans des représentations décimales; tous les nombres décimaux ne sont pas exactement représentables en virgule flottante binaire - 0,1, par exemple - donc si vous utilisez une valeur en virgule flottante binaire, vous obtiendrez en fait une approximation de 0,1. Vous obtiendrez toujours des approximations lorsque vous utilisez un point décimal flottant également - le résultat de la division de 1 par 3 ne peut pas être représenté exactement, par exemple.
Quant à quoi utiliser quand:
Pour les valeurs qui sont des "décimales naturellement exactes", il est bon d'utiliser
decimal
. Cela convient généralement à tous les concepts inventés par l'homme: les valeurs financières sont l'exemple le plus évident, mais il y en a d'autres aussi. Considérez le score donné aux plongeurs ou aux patineurs, par exemple.Pour les valeurs qui sont davantage des artefacts de la nature qui ne peuvent pas vraiment être mesurés exactement de toute façon,
float
/double
sont plus appropriées. Par exemple, les données scientifiques sont généralement représentées sous cette forme. Ici, les valeurs d'origine ne seront pas "d'une précision décimale" pour commencer, il n'est donc pas important pour les résultats attendus de maintenir la "précision décimale". Les types à virgule binaire flottante sont beaucoup plus rapides à utiliser que les décimales.la source
float
/double
ne représentent généralement pas des nombres car101.101110
, normalement, il est représenté comme quelque chose comme1101010 * 2^(01010010)
- un exposantfloat
c'est un mot-clé d'alias C # et ce n'est pas un type .Net. c'estSystem.Single
..single
etdouble
sont des types de points binaires flottants.La précision est la principale différence.
Flottant - 7 chiffres (32 bits)
Double -15-16 chiffres (64 bits)
Décimal -28-29 chiffres significatifs (128 bits)
Les décimales ont une précision beaucoup plus élevée et sont généralement utilisées dans les applications financières qui nécessitent un haut degré de précision. Les décimales sont beaucoup plus lentes (jusqu'à 20 fois dans certains tests) qu'un double / flottant.
Les décimales et les flottants / doubles ne peuvent pas être comparés sans lancer, contrairement aux flottants et doubles. Les décimales permettent également l'encodage ou les zéros de fin.
Résultat :
la source
0.1
- ce qui est rarement le cas dans le monde réel! Tout format de stockage fini confondra un nombre infini de valeurs possibles en un nombre fini de motifs binaires. Par exemple,float
va fusionner0.1
et0.1 + 1e-8
, tandis quedecimal
va fusionner0.1
et0.1 + 1e-29
. Bien sûr, dans une plage donnée , certaines valeurs peuvent être représentées dans n'importe quel format avec une perte de précision nulle (par exemple,float
peuvent stocker n'importe quel entier jusqu'à 1,6e7 avec une perte de précision nulle) - mais ce n'est toujours pas une précision infinie .0.1
n'est pas une valeur spéciale ! La seule chose qui fait0.1
"mieux" que0.10000001
c'est parce que les êtres humains aiment la base 10. Et même avec unefloat
valeur, si vous initialisez deux valeurs de0.1
la même manière, elles auront toutes les deux la même valeur . C'est juste que cette valeur ne sera pas exactement0.1
- ce sera la valeur la plus proche de0.1
celle qui peut être représentée exactement comme unfloat
. Bien sûr, avec des flottants binaires(1.0 / 10) * 10 != 1.0
, mais avec des flottants décimaux(1.0 / 3) * 3 != 1.0
non plus. Ni l'un ni l'autre n'est parfaitement précis.double a = 0.1; double b = 0.1;
cea == b
sera vrai . Il est juste que ,a
etb
sera à la fois pas tout à fait égal0.1
. En C #, si vous le faitesdecimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;
alorsa == b
également être vrai. Mais dans ce cas, ni dea
nib
sera exactement égale1/3
- ils seront tous deux égaux0.3333...
. Dans les deux cas, une certaine précision est perdue en raison de la représentation. Vous dites obstinément que ladecimal
précision est "infinie", ce qui est faux .La structure décimale est strictement adaptée aux calculs financiers nécessitant une précision, qui sont relativement peu tolérants à l'arrondi. Cependant, les décimales ne conviennent pas aux applications scientifiques pour plusieurs raisons:
la source
Voir ici pour plus d'informations .
la source
Je ne répéterai pas des tonnes de bonnes (et certaines mauvaises) informations déjà répondues dans d'autres réponses et commentaires, mais je répondrai à votre question de suivi avec un conseil:
Utiliser décimal pour les valeurs comptées
Utiliser float / double pour les valeurs mesurées
Quelques exemples:
l'argent (comptons-nous l'argent ou mesurons-nous l'argent?)
distance (comptons-nous la distance ou mesurons-nous la distance? *)
scores (comptons-nous les scores ou mesurons-nous les scores?)
Nous comptons toujours l'argent et ne devons jamais le mesurer. Nous mesurons généralement la distance. Nous comptons souvent des scores.
* Dans certains cas, ce que j'appellerais la distance nominale , nous pouvons en effet vouloir «compter» la distance. Par exemple, nous avons peut-être affaire à des signes de pays qui montrent des distances aux villes, et nous savons que ces distances n'ont jamais plus d'un chiffre décimal (xxx.x km).
la source
float
7 chiffres de précisiondouble
a environ 15 chiffres de précisiondecimal
a environ 28 chiffres de précisionSi vous avez besoin d'une meilleure précision, utilisez double au lieu de float. Dans les processeurs modernes, les deux types de données ont presque les mêmes performances. Le seul avantage de l'utilisation de flotteur est qu'ils prennent moins de place. N'importe pratiquement que si vous en avez plusieurs.
J'ai trouvé que c'était intéressant. Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante
la source
double
approprié dans les applications comptables dans les cas (et en gros seulement dans ces cas) où aucun type entier supérieur à 32 bits n'était disponible, et ledouble
était utilisé comme s'il s'agissait d'un type entier 53 bits (par exemple pour maintenir un nombre entier de centimes, ou un nombre entier de centièmes de cent). De nos jours, ces choses ne sont pas très utiles, mais de nombreuses langues ont acquis la possibilité d'utiliser des valeurs à virgule flottante double précision bien avant de gagner des mathématiques entières 64 bits (ou même dans certains cas 32 bits!).Real
IIRC pouvait représenter des valeurs allant jusqu'à 1,8E + 19 avec une précision unitaire. Je pense qu'il serait beaucoup plus sain pour une application de comptabilité d'utiliserReal
pour représenter un nombre entier de sous que ...double
type qui avait une précision d'unité allant jusqu'à 9E15. Si l'on a besoin de stocker des nombres entiers qui sont plus grands que le plus grand type entier disponible, l'utilisationdouble
est susceptible d'être plus simple et plus efficace que d'essayer de truquer les mathématiques multi-précision, d'autant plus que les processeurs ont des instructions pour effectuer 16x16-> 32 ou. ..Personne n'a mentionné que
je veux dire
lève OverflowException .
Mais ceux-ci ne:
&
la source
float.MaxValue+1 == float.MaxValue
, tout commedecimal.MaxValue+0.1D == decimal.MaxValue
. Peut-être que vous vouliez dire quelque chose comme çafloat.MaxValue*2
?System.Decimal
lève une exception juste avant qu'il ne devienne incapable de distinguer des unités entières, mais si une application est censée traiter par exemple des dollars et des cents, cela pourrait être trop tard.la source
decimal
par zéro (CS0020), et il en va de même pour les littéraux intégraux. Cependant, si une valeur décimale d'exécution est divisée par zéro, vous obtiendrez une exception et non une erreur de compilation.Les nombres entiers, comme cela a été mentionné, sont des nombres entiers. Ils ne peuvent pas stocker le point quelque chose, comme .7, .42 et .007. Si vous devez stocker des nombres qui ne sont pas des nombres entiers, vous avez besoin d'un type de variable différent. Vous pouvez utiliser le type double ou le type flottant. Vous définissez ces types de variables exactement de la même manière: au lieu d'utiliser le mot
int
, vous tapezdouble
oufloat
. Comme ça:(
float
est l'abréviation de "virgule flottante", et signifie simplement un nombre avec un point quelque chose à la fin.)La différence entre les deux réside dans la taille des numéros qu'ils peuvent contenir. Pour
float
, vous pouvez avoir jusqu'à 7 chiffres dans votre numéro. Pourdouble
s, vous pouvez avoir jusqu'à 16 chiffres. Pour être plus précis, voici la taille officielle:float
est un nombre 32 bits etdouble
est un nombre 64 bits.Double-cliquez sur votre nouveau bouton pour accéder au code. Ajoutez les trois lignes suivantes à votre code de bouton:
Arrêtez votre programme et revenez à la fenêtre de codage. Modifiez cette ligne:
Exécutez votre programme et cliquez sur votre double bouton. La boîte de message affiche correctement le numéro. Ajoutez un autre nombre à la fin, cependant, et C # arrondira à nouveau vers le haut ou vers le bas. La morale est que si vous voulez de la précision, faites attention à l'arrondi!
la source
la source
decimal
est en fait stocké au format décimal (par opposition à la base 2; il ne perdra donc pas les chiffres en raison de la conversion entre les deux systèmes numériques); en outre,decimal
n'a aucun concept de valeurs spéciales telles que NaN, -0, ∞ ou -∞.Cela a été un fil intéressant pour moi, car aujourd'hui, nous venons d'avoir un petit bug méchant, concernant
decimal
avoir moins de précision qu'unfloat
.Dans notre code C #, nous lisons les valeurs numériques d'une feuille de calcul Excel, les convertissons en un
decimal
, puis les renvoyonsdecimal
à un service pour les enregistrer dans une base de données SQL Server .Maintenant, pour presque toutes nos valeurs Excel, cela a fonctionné à merveille. Mais pour certaines très petites valeurs Excel, l'utilisation a
decimal.TryParse
complètement perdu la valeur. Un tel exemple estcellValue = 0,00006317592
Decimal.TryParse (cellValue.ToString (), out value); // retournerait 0
La solution, bizarrement, était de convertir les valeurs Excel en une
double
première, puis endecimal
:Même s'il
double
a moins de précision qu'un adecimal
, cela garantissait en fait que les petits nombres seraient toujours reconnus. Pour une raison quelconque,double.TryParse
était en fait en mesure de récupérer de si petits nombres, toutdecimal.TryParse
en les mettant à zéro.Impair. Très étrange.
la source
decimal.Parse("0.00006317592")
ça marche - vous avez autre chose en cours. - Peut-être une notation scientifique?Pour les applications telles que les jeux et les systèmes embarqués où la mémoire et les performances sont toutes deux critiques, le flottant est généralement le type numérique de choix car il est plus rapide et deux fois plus petit. Les entiers étaient l'arme de choix, mais les performances en virgule flottante ont dépassé l'entier dans les processeurs modernes. Decimal est sorti!
la source
Les types de variables Decimal, Double et Float sont différents dans la façon dont ils stockent les valeurs. La précision est la principale différence lorsque float est un type de données à virgule flottante simple précision (32 bits), double est un type de données à virgule flottante double précision (64 bits) et décimal est un type de données à virgule flottante 128 bits.
Flottant - 32 bits (7 chiffres)
Double - 64 bits (15-16 chiffres)
Décimal - 128 bits (28-29 chiffres significatifs)
En savoir plus ... la différence entre Decimal, Float et Double
la source
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 valeur contient la variable bLower?
Réponse: Sur une machine 32 bits, bLower contient TRUE !!!
Si je remplace Double par Decimal, bLower contient FALSE qui est la bonne réponse.
En double, le problème est que fMean-fDelta = 1.09999999999 qui est inférieur à 1.1.
Attention: je pense que le même problème peut certainement exister pour d'autres nombres car Decimal n'est qu'un double avec une précision plus élevée et la précision a toujours une limite.
En fait, Double, Float et Decimal correspondent à la décimale BINARY dans COBOL!
Il est regrettable que d'autres types numériques implémentés dans COBOL n'existent pas dans .Net. Pour ceux qui ne connaissent pas COBOL, il existe en COBOL le type numérique suivant
la source
En termes simples:
la source
Decimal
approprié pour les applications financières, et c'est le principal critère à utiliser pour décider entreDecimal
etDouble
. Il est rare que laDouble
précision ne soit pas suffisante pour des applications scientifiques, par exemple (etDecimal
est souvent inadaptée aux applications scientifiques en raison de sa portée limitée).La principale différence entre chacun d'eux est la précision.
float
est un32-bit
nombre,double
est un64-bit
nombre etdecimal
est un128-bit
nombre.la source
Décimal 128 bits (28-29 chiffres significatifs) Dans le cas d'applications financières, il est préférable d'utiliser les types décimaux car il vous donne un haut niveau de précision et facile à éviter les erreurs d'arrondi Utilisez décimal pour les mathématiques non entières où la précision est nécessaire (par exemple argent et monnaie)
Double 64 bits (15-16 chiffres) Les types doubles sont probablement le type de données le plus utilisé pour les valeurs réelles, à l'exception de la gestion de l'argent. Utilisez double pour les mathématiques non entières où la réponse la plus précise n'est pas nécessaire.
Float 32 bits (7 chiffres) Il est principalement utilisé dans les bibliothèques graphiques car les demandes de puissance de traitement sont très élevées, ce qui permet également des situations pouvant supporter des erreurs d'arrondi.
Decimals
sont beaucoup plus lents qu'undouble/float
.Decimals
etFloats/Doubles
ne peut pas être comparé sans un casting alors queFloats
etDoubles
peut.Decimals
autorise également le codage ou les zéros de fin.la source
Pour définir Decimal, Float et Double dans .Net (c #)
vous devez mentionner les valeurs comme:
et vérifiez les résultats.
Et les octets occupés par chacun sont
la source