Différence entre décimal, float et double dans .NET?

Réponses:

2267

floatet doublesont des types de points binaires flottants . En d'autres termes, ils représentent un nombre comme celui-ci:

10001.10010110011

Le nombre binaire et l'emplacement du point binaire sont tous deux codés dans la valeur.

decimalest une variable décimale type de point . En d'autres termes, ils représentent un nombre comme celui-ci:

12345.65789

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 decimaltoujours 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/ doublesont 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.

Jon Skeet
la source
58
float/ doublene représentent généralement pas des nombres car 101.101110, normalement, il est représenté comme quelque chose comme 1101010 * 2^(01010010)- un exposant
Mingwei Samuel
79
@Hazzard: C'est ce que signifie la partie "et l'emplacement du point binaire" de la réponse.
Jon Skeet
112
Je suis surpris qu'il n'ait pas déjà été dit, floatc'est un mot-clé d'alias C # et ce n'est pas un type .Net. c'est System.Single.. singleet doublesont des types de points binaires flottants.
Brett Caswell
54
@BKSpurgeon: Eh bien, seulement de la même manière que vous pouvez dire que tout est de type binaire, à quel point cela devient une définition assez inutile. Decimal est un type décimal dans la mesure où il s'agit d'un nombre représenté sous la forme d'un entier et d'une échelle, de sorte que le résultat est une échelle de 10 *, tandis que float et double sont une échelle de 2 *. Vous prenez un nombre écrit en décimal et déplacez le point décimal suffisamment vers la droite pour avoir un entier pour calculer la signification et l'échelle. Pour float / double, vous commenceriez par un nombre écrit en binaire.
Jon Skeet
21
Autre différence: float 32 bits; double 64 bits; et décimal 128 bits.
David
1073

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.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Résultat :

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333
cgreeno
la source
65
@Thecrocodilehunter: désolé, mais non. Decimal peut représenter tous les nombres qui peuvent être représentés en notation décimale, mais pas 1/3 par exemple. 1,0 m / 3,0 m sera évalué à 0,33333333 ... avec un nombre important mais fini de 3 à la fin. La multiplier par 3 ne renverra pas un 1.0 exact.
Erik P.
50
@Thecrocodilehunter: Je pense que vous confondez exactitude et précision. Ce sont des choses différentes dans ce contexte. La précision est le nombre de chiffres disponibles pour représenter un nombre. Plus vous avez de précision, moins vous avez besoin d'arrondir. Aucun type de données n'a une précision infinie.
Igby Largeman
13
@Thecrocodilehunter: Vous supposez que la valeur qui est mesurée est exactement 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, floatva fusionner 0.1et 0.1 + 1e-8, tandis que decimalva fusionner 0.1et 0.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, floatpeuvent 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 .
Daniel Pryden
27
@Thecrocodilehunter: Vous avez manqué mon point. 0.1n'est pas une valeur spéciale ! La seule chose qui fait 0.1"mieux" que 0.10000001c'est parce que les êtres humains aiment la base 10. Et même avec une floatvaleur, si vous initialisez deux valeurs de 0.1la même manière, elles auront toutes les deux la même valeur . C'est juste que cette valeur ne sera pas exactement 0.1 - ce sera la valeur la plus proche de 0.1celle 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.0non plus. Ni l'un ni l'autre n'est parfaitement précis.
Daniel Pryden
16
@Thecrocodilehunter: Vous ne comprenez toujours pas. Je ne sais pas comment le dire plus clairement: en C, si vous le faites, double a = 0.1; double b = 0.1;ce a == b sera vrai . Il est juste que , aet bsera à la fois pas tout à fait égal 0.1. En C #, si vous le faites decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;alors a == bégalement être vrai. Mais dans ce cas, ni de ani bsera exactement égale 1/3- ils seront tous deux égaux 0.3333.... Dans les deux cas, une certaine précision est perdue en raison de la représentation. Vous dites obstinément que la decimalprécision est "infinie", ce qui est faux .
Daniel Pryden
84

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:

  • Une certaine perte de précision est acceptable dans de nombreux calculs scientifiques en raison des limites pratiques du problème physique ou de l'artefact mesuré. La perte de précision n'est pas acceptable en finance.
  • Decimal est beaucoup (beaucoup) plus lent que float et double pour la plupart des opérations, principalement parce que les opérations en virgule flottante sont effectuées en binaire, tandis que Decimal se fait en base 10 (c'est-à-dire que les flottants et les doubles sont gérés par le matériel FPU, comme MMX / SSE , alors que les décimales sont calculées dans le logiciel).
  • Decimal a une plage de valeurs inacceptablement plus petite que double, malgré le fait qu'il prend en charge plus de chiffres de précision. Par conséquent, Decimal ne peut pas être utilisé pour représenter de nombreuses valeurs scientifiques.
Mark Jones
la source
5
Si vous faites des calculs financiers, vous devez absolument rouler vos propres types de données ou trouver une bonne bibliothèque qui correspond à vos besoins exacts. La précision dans un contexte financier est définie par des organismes de normalisation (humains) et ils ont des règles localisées très précises (à la fois dans le temps et sur le plan géographique) sur la façon de faire des calculs. Des choses comme l'arrondi correct ne sont pas capturées dans les types de données numériques simples de .Net. La capacité de faire des calculs n'est qu'une très petite partie du puzzle.
James Moore
76
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Voir ici pour plus d'informations .

Uwe Keim
la source
5
Vous avez omis la plus grande différence, qui est la base utilisée pour le type décimal (la décimale est stockée comme base 10, tous les autres types numériques répertoriés sont la base 2).
BrainSlugs83
1
Les plages de valeurs pour le simple et le double ne sont pas représentées correctement dans l'image ci-dessus ou dans le message du forum source. Comme nous ne pouvons pas facilement exposer le texte ici, utilisez le caractère caret: Single doit être 10 ^ -45 et 10 ^ 38, et Double doit être 10 ^ -324 et 10 ^ 308. De plus, MSDN a le flotteur avec une plage de -3,4x10 ^ 38 à + 3,4x10 ^ 38. Recherchez dans MSDN System.Single et System.Double en cas de changement de lien. Simple: msdn.microsoft.com/en-us/library/b1e65aza.aspx Double: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee
2
La décimale est de 128 bits ... signifie qu'elle occupe 16 octets et non 12
user1477332
51

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:

Quand quelqu'un en utiliserait-il un?

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

tomosius
la source
1
J'aime vraiment cette réponse, en particulier la question "comptons-nous ou mesurons-nous l'argent?" Cependant, à part l'argent, je ne peux penser à rien de «compté» qui ne soit pas simplement un entier. J'ai vu certaines applications qui utilisent la décimale simplement parce que double a trop peu de chiffres significatifs. En d'autres termes, la décimale peut être utilisée car C # n'a pas de type quadruple en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
John Henckel
48

float 7 chiffres de précision

double a environ 15 chiffres de précision

decimal a environ 28 chiffres de précision

Si 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

CharithJ
la source
1
@RogerLipscombe: Je considérerais doubleapproprié 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 le doubleé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!).
supercat
1
Votre réponse implique que la précision est la seule différence entre ces types de données. Étant donné que l'arithmétique à virgule flottante binaire est généralement implémentée dans le FPU matériel , les performances sont une différence significative. Cela peut être sans conséquence pour certaines applications, mais est critique pour d'autres.
saille
6
@supercat double n'est jamais approprié dans les applications comptables. Parce que Double ne peut qu'approcher des valeurs décimales (même dans la plage de sa propre précision). Cela est dû au fait que double stocke les valeurs dans un format centré en base 2 (binaire).
BrainSlugs83
2
@ BrainSlugs83: L'utilisation de types à virgule flottante pour contenir des quantités non entières serait incorrecte, mais il était historiquement très courant que les langues aient des types à virgule flottante qui pourraient représenter avec précision des valeurs entières plus grandes que leurs types entiers pourraient représenter. . L'exemple le plus extrême était peut-être le Turbo-87 dont les seuls types entiers étaient limités de -32768 à +32767, mais dont l' RealIIRC 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'utiliser Realpour représenter un nombre entier de sous que ...
supercat
1
... pour qu'il essaie d'effectuer des mathématiques multi-précision en utilisant un tas de valeurs 16 bits. Pour la plupart des autres langues, la différence n'était pas si extrême, mais pendant longtemps, il a été très courant que les langues n'aient pas de type entier dépassant 4E9 mais aient un doubletype 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'utilisation doubleest 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. ..
supercat
36

Personne n'a mentionné que

Dans les paramètres par défaut, Floats (System.Single) et doubles (System.Double) n'utiliseront jamais la vérification de débordement tandis que Decimal (System.Decimal) utilisera toujours la vérification de débordement.

je veux dire

decimal myNumber = decimal.MaxValue;
myNumber += 1;

lève OverflowException .

Mais ceux-ci ne:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;
GorkemHalulu
la source
1
float.MaxValue+1 == float.MaxValue, tout comme decimal.MaxValue+0.1D == decimal.MaxValue. Peut-être que vous vouliez dire quelque chose comme ça float.MaxValue*2?
supercat
@supercar Mais il n'est pas vrai que decimal.MaxValue + 1 == decimal.MaxValue
GorkemHalulu
@supercar decimal.MaxValue + 0.1m == decimal.MaxValue ok
GorkemHalulu
1
Le System.Decimallè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.
supercat
28
  1. Double et float peuvent être divisés par zéro entier sans exception à la fois lors de la compilation et de l'exécution.
  2. Le nombre décimal ne peut pas être divisé par un entier zéro. La compilation échouera toujours si vous faites cela.
xport
la source
6
Ils le peuvent bien sûr! Ils ont également quelques valeurs "magiques" telles que Infinity, Negative Infinity et NaN (pas un nombre) qui le rendent très utile pour détecter les lignes verticales lors du calcul des pentes ... De plus, si vous devez décider entre appeler float .TryParse, double.TryParse et decimal.TryParse (pour détecter si une chaîne est un nombre, par exemple), je recommande d'utiliser double ou float, car ils analyseront correctement "Infinity", "-Infinity" et "NaN" , alors que la décimale ne le sera pas.
BrainSlugs83
La compilation échoue uniquement si vous essayez de diviser un littéral decimalpar 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.
Drew Noakes
@ BrainSlugs83 Cependant, vous pouvez ne pas vouloir analyser "Infinity" ou "NaN" selon le contexte. Semble être un bon exploit pour la saisie des utilisateurs si le développeur n'est pas assez rigoureux.
Hiver
28

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 tapez doubleou float. Comme ça:

float myFloat;
double myDouble;

( floatest 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. Pour doubles, vous pouvez avoir jusqu'à 16 chiffres. Pour être plus précis, voici la taille officielle:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

floatest un nombre 32 bits et doubleest un nombre 64 bits.

Double-cliquez sur votre nouveau bouton pour accéder au code. Ajoutez les trois lignes suivantes à votre code de bouton:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Arrêtez votre programme et revenez à la fenêtre de codage. Modifiez cette ligne:

myDouble = 0.007;
myDouble = 12345678.1234567;

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!

daniel
la source
2
Le «point quelque chose» que vous avez mentionné est généralement appelé «la partie fractionnaire» d'un nombre. "Virgule flottante" ne signifie pas "un nombre avec un point quelque chose à la fin"; mais au lieu de cela, "virgule flottante" distingue le type de nombre, par opposition à un nombre de "point fixe" (qui peut également stocker une valeur fractionnaire); la différence est de savoir si la précision est fixe ou flottante. - Les nombres à virgule flottante vous donnent une plage dynamique de valeurs beaucoup plus grande (Min et Max), au détriment de la précision, tandis qu'un nombre à virgule fixe vous donne une précision constante au coût de la plage.
BrainSlugs83
16
  • flotteur: ± 1,5 x 10 ^ -45 à ± 3,4 x 10 ^ 38 (~ 7 chiffres significatifs
  • double: ± 5,0 x 10 ^ -324 à ± 1,7 x 10 ^ 308 (15-16 chiffres significatifs)
  • décimal: ± 1,0 x 10 ^ -28 à ± 7,9 x 10 ^ 28 (28-29 chiffres significatifs)
Mukesh Kumar
la source
9
La différence est plus qu'une simple précision. - decimalest 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, decimaln'a aucun concept de valeurs spéciales telles que NaN, -0, ∞ ou -∞.
BrainSlugs83
13

Cela a été un fil intéressant pour moi, car aujourd'hui, nous venons d'avoir un petit bug méchant, concernant decimalavoir moins de précision qu'un float.

Dans notre code C #, nous lisons les valeurs numériques d'une feuille de calcul Excel, les convertissons en un decimal, puis les renvoyons decimalà un service pour les enregistrer dans une base de données SQL Server .

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Maintenant, pour presque toutes nos valeurs Excel, cela a fonctionné à merveille. Mais pour certaines très petites valeurs Excel, l'utilisation a decimal.TryParsecomplètement perdu la valeur. Un tel exemple est

  • cellValue = 0,00006317592

  • Decimal.TryParse (cellValue.ToString (), out value); // retournerait 0

La solution, bizarrement, était de convertir les valeurs Excel en une doublepremière, puis en decimal:

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    
}

Même s'il doublea moins de précision qu'un a decimal, 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, tout decimal.TryParseen les mettant à zéro.

Impair. Très étrange.

Mike Gledhill
la source
3
Par curiosité, quelle était la valeur brute de cellValue.ToString ()? Decimal.TryParse ("0.00006317592", out val) semble fonctionner ...
micahtan
11
-1 Ne vous méprenez pas, si c'est vrai, c'est très intéressant mais c'est une question distincte, ce n'est certainement pas une réponse à cette question.
Weston
2
Peut-être parce que la cellule Excel renvoyait un double et que la valeur ToString () était "6.31759E-05", donc decimal.Parse () n'aimait pas la notation. Je parie que si vous aviez vérifié la valeur de retour de Decimal.TryParse (), cela aurait été faux.
SergioL
2
@weston Les réponses complètent souvent les autres réponses en remplissant les nuances qu'elles ont manquées. Cette réponse met en évidence une différence en termes d'analyse. C'est vraiment une réponse à la question!
Robino
1
Euh ... decimal.Parse("0.00006317592")ça marche - vous avez autre chose en cours. - Peut-être une notation scientifique?
BrainSlugs83
9

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!

yo-yo
la source
Presque tous les systèmes modernes, même les téléphones portables, ont un support matériel pour le double; et si votre jeu a même une physique simple, vous remarquerez une grande différence entre double et float. (Par exemple, le calcul de la vitesse / frottement dans un simple clone Asteroids, double accélération permettent de circuler beaucoup plus fluide que float -. On dirait que ce ne devrait pas la matière, mais elle tout à fait.)
BrainSlugs83
Les doubles sont également deux fois plus volumineux, ce qui signifie que vous devez parcourir deux fois plus de données, ce qui nuit aux performances de votre cache. Comme toujours, mesurez et procédez en conséquence.
yoyo
7

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

warnerl
la source
5

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

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

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

BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte) 
schlebe
la source
4

En termes simples:

  1. Les types de variables Decimal, Double et Float sont différents dans la façon dont ils stockent les valeurs.
  2. La précision est la principale différence (notez que ce n'est pas la seule différence) où 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 128 bits type de données à virgule flottante.
  3. Le tableau récapitulatif:

/==========================================================================================
    Type       Bits    Have up to                   Approximate Range 
/==========================================================================================
    float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
    double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
    decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Vous pouvez en savoir plus ici , Float , Double et Decimal .

GntS
la source
Qu'ajoute cette réponse qui n'est pas déjà couverte dans les réponses existantes? BTW, votre "ou" dans la ligne "décimale" est incorrect: la barre oblique dans la page Web que vous copiez indique une division plutôt qu'une alternative.
Mark Dickinson
1
Et je contesterais fortement que la précision est la principale différence. La principale différence est la base: virgule flottante décimale contre virgule flottante binaire. Cette différence est ce qui rend Decimalapproprié pour les applications financières, et c'est le principal critère à utiliser pour décider entre Decimalet Double. Il est rare que la Doublepré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).
Mark Dickinson
2

La principale différence entre chacun d'eux est la précision.

floatest un 32-bitnombre, doubleest un 64-bitnombre et decimalest un 128-bitnombre.

user3776645
la source
0
  • 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.

Decimalssont beaucoup plus lents qu'un double/float.

Decimalset Floats/Doublesne peut pas être comparé sans un casting alors que Floatset Doublespeut.

Decimals autorise également le codage ou les zéros de fin.

Reza Jenabi
la source
-1

Pour définir Decimal, Float et Double dans .Net (c #)

vous devez mentionner les valeurs comme:

Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;

et vérifiez les résultats.

Et les octets occupés par chacun sont

Float - 4
Double - 8
Decimal - 12
Purnima Bhatia
la source