floating-point decimal - Différence entre décimal, float et double dans.NET?




difference vs (15)

Quelle est la différence entre decimal , float et double dans .NET?

Quand est-ce que quelqu'un en utiliserait un?


Answers

pour plus d'informations vous pouvez aller à la source de cette image:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5


Je ne vais pas répéter des tonnes de bonnes (et quelques mauvaises) informations déjà répondu dans d'autres réponses et commentaires, mais je vais répondre à votre question de suivi avec un conseil:

Quand est-ce que quelqu'un en utiliserait un?

Utiliser la décimale pour les valeurs comptées

Utiliser float / double pour les valeurs mesurées

Quelques exemples:

  • l'argent (est-ce qu'on compte l'argent ou mesure l'argent?)

  • distance (compte-t-on la distance ou la distance de mesure? *)

  • scores (compte-t-on les scores ou les scores?)

Nous comptons toujours l'argent et ne devrions jamais le mesurer. Nous mesurons habituellement la distance. Nous comptons souvent les scores.

* Dans certains cas, ce que j'appellerais la distance nominale , nous pouvons en effet vouloir «compter» la distance. Par exemple, nous traitons peut-être des signes de pays qui indiquent les distances par rapport aux villes, et nous savons que ces distances n'ont jamais plus d'un chiffre décimal (xxx.x km).


Les types de variable 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 de 128 bits.

Flotteur - 32 bits (7 chiffres)

Double - 64 bits (15-16 chiffres)

Décimal - 128 bits (28 à 29 chiffres significatifs)

Plus sur ... la différence entre Decimal, Float et Double


La structure Decimal est strictement orientée vers les calculs financiers nécessitant une précision, qui sont relativement intolérants à l'arrondissement. Les nombres décimaux ne sont pas adéquats pour des applications scientifiques, cependant, 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 se font en binaire, alors que Decimal est fait en base 10 (les flotteurs 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 supporte plus de chiffres de précision. Par conséquent, Decimal ne peut pas être utilisé pour représenter de nombreuses valeurs scientifiques.

Cela a été un fil intéressant pour moi, car aujourd'hui, nous venons d'avoir un petit bug méchant, concernant la decimal ayant 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 nombre decimal , puis renvoyons cette decimal à un service pour 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é magnifiquement. Mais pour certains, très petites valeurs Excel, en utilisant decimal.TryParse perdu la valeur. Un tel exemple est

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), valeur de sortie); // retournerait 0

La solution, bizarrement, était de convertir les valeurs Excel en un double premier, puis en un nombre 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 si le double a moins de précision qu'une decimal , cela garantit que de petits nombres seront toujours reconnus. Pour une raison quelconque, double.TryParse était réellement capable de récupérer de tels petits nombres, alors que decimal.TryParse mettrait à zéro.

Impair. Très étrange.


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 est la valeur de la variable bLower?

Réponse: Sur une machine 32 bits, bLower contient TRUE !!!

Si je remplace Double par Decimal, bLower contient FALSE, ce qui est la bonne réponse.

En double, le problème est que fMean-fDelta = 1.09999999999 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 dans COBOL suivant le type numérique

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) 

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 le double au lieu du flotteur. Dans les processeurs modernes, les deux types de données ont presque les mêmes performances. Le seul avantage d'utiliser float est qu'ils occupent moins d'espace. Pratiquement importe seulement si vous en avez beaucoup.

J'ai trouvé cela intéressant. Ce que tout informaticien devrait savoir sur l'arithmétique en virgule flottante


La précision est la principale différence.

Float - 7 chiffres (32 bits)

Double -15-16 chiffres (64 bits)

Decimal -28-29 chiffres significatifs (128 bits)

Les nombres décimaux ont une précision beaucoup plus élevée et sont généralement utilisés dans des applications financières nécessitant un haut degré de précision. Les nombres décimaux sont beaucoup plus lents (jusqu'à 20 fois dans certains tests) qu'un double / flotteur.

Les nombres décimaux et les nombres flottants / doubles ne peuvent pas être comparés sans le lancer alors que les nombres flottants et doubles le peuvent. Les nombres décimaux autorisent également les zéros de codage ou 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

Les types de variable 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 de 128 bits.

Flotteur - 32 bits (7 chiffres)

Double - 64 bits (15-16 chiffres)

Décimal - 128 bits (28 à 29 chiffres significatifs)

La principale différence est que Floats et Doubles sont des types à virgule flottante binaire et un Decimal stocke la valeur sous forme de virgule décimale flottante. Les décimales ont donc une précision beaucoup plus grande et sont généralement utilisées dans des applications de calcul monétaires (financières) ou scientifiques nécessitant un haut degré de précision. Mais en termes de performances, les nombres décimaux sont plus lents que les types double et flottant.

Décimal peut 100% représenter avec précision n'importe quel nombre dans la précision du format décimal, tandis que Float et Double, ne peut pas représenter avec précision tous les nombres, même les chiffres qui sont dans leurs formats respectifs de précision.

Décimal

Dans le cas d'applications financières, ou de calculs scientifiques, il est préférable d'utiliser les types décimaux car cela vous donne un haut niveau de précision et évite facilement les erreurs d'arrondi

Double

Les types doubles sont probablement le type de données le plus couramment utilisé pour les valeurs réelles, à l'exception du traitement de l'argent.

Flotte

Il est principalement utilisé dans les bibliothèques graphiques car les demandes de puissances de traitement sont très élevées et les situations d'utilisation peuvent supporter des erreurs d'arrondi.


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

float est un nombre de 32-bit , double est un nombre de 64-bit et decimal est un nombre de 128-bit .


  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. La décimale ne peut pas être divisée par zéro entier. La compilation échouera toujours si vous faites cela.

Flotter ~ ± 1,5 x 10-45 à ± 3,4 x 1038 -------- 7 chiffres
double ~ ± 5,0 x 10-324 à ± 1,7 x 10308 ------ 15 ou 16 chiffres
décimal ~ ± 1,0 x 10-28 à ± 7,9 x 1028 -------- 28 ou 29 chiffres


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 float. Vous définissez ces types de variables exactement de la même manière: au lieu d'utiliser le mot int , vous tapez double ou float . Comme ça:

float myFloat;
double myDouble;

( float est l'abréviation de "floating point", et signifie simplement un nombre avec un point quelque chose à la fin.)

La différence entre les deux est dans la taille des nombres qu'ils peuvent contenir. Pour float , vous pouvez avoir jusqu'à 7 chiffres dans votre numéro. Pour les double , 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

float est un nombre de 32 bits et double est un nombre de 64 bits.

Double-cliquez sur votre nouveau bouton pour obtenir le 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. Changez 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. Ajouter un autre nombre à la fin, cependant, et C # sera à nouveau arrondi vers le haut ou vers le bas. La morale est que si vous voulez de l'exactitude, faites attention aux arrondis!


Personne n'a mentionné cela

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

je veux dire

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

throws OverflowException .

Mais ceux-ci ne le font pas:

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

&

double myNumber = double.MaxValue;
myNumber += 1;

Paramètres Ref et Out:

Les paramètres out et ref sont utilisés pour renvoyer des valeurs dans la même variable, que vous passez en argument d'une méthode. Ces deux paramètres sont très utiles lorsque votre méthode doit renvoyer plusieurs valeurs.

Vous devez affecter une valeur au paramètre out dans le corps de la méthode calee, sinon la méthode ne sera pas compilée.

Ref Parameter: Il doit être initialisé avant de passer à la méthode. Le mot-clé ref sur un paramètre de méthode fait référence à une méthode qui fait référence à la même variable qui a été transmise en tant que paramètre d'entrée pour la même méthode. Si vous faites des changements à la variable, ils seront reflétés dans la variable.

int sampleData = 0; 
sampleMethod(ref sampleData);

Ex de paramètre Ref

public static void Main() 
{ 
 int i = 3; // Variable need to be initialized 
 sampleMethod(ref i );  
}

public static void sampleMethod(ref int sampleData) 
{ 
 sampleData++; 
} 

Out Parameter: Il n'est pas nécessaire d'être initialisé avant de passer à Method. Le paramètre out peut être utilisé pour renvoyer les valeurs de la même variable passée en paramètre de la méthode. Toute modification apportée au paramètre sera reflétée dans la variable.

 int sampleData; 
 sampleMethod(out sampleData);

Ex de Out Parameter

public static void Main() 
{ 
 int i, j; // Variable need not be initialized 
 sampleMethod(out i, out j); 
} 
public static int sampleMethod(out int sampleData1, out int sampleData2) 
{ 
 sampleData1 = 10; 
 sampleData2 = 20; 
 return 0; 
} 




.net floating-point double decimal