277 votes

Quand dois-je utiliser double au lieu de decimal ?

Je peux nommer trois avantages de l'utilisation de double (ou float) au lieu de decimal:

  1. Utilise moins de mémoire.
  2. Plus rapide, car à virgule flottante opérations mathématiques sont pris en charge nativement par les transformateurs.
  3. Peut représenter une plus grande gamme de nombres.

Mais ces avantages semblent s'appliquent uniquement au calcul intensif opérations, tels que ceux trouvés dans les logiciels de modélisation. Bien sûr, le double ne doit pas être utilisé lorsque la précision est requise, comme les calculs financiers. Alors y at-il des raisons pratiques à jamais choisir double (ou float) au lieu de decimal dans des applications "normales"?

Edité pour ajouter: Merci pour toutes ces excellentes réponses, j'ai appris d'eux.

Une autre question: quelques personnes ont fait le point de doubles peut plus représenter des nombres réels. Lors de sa déclaration, je pense que, en général, avec plus de précision les représenter. Mais est-il un énoncé vrai que la précision peut diminuer (parfois considérablement) lors d'opérations en virgule flottante sont effectuées?

314voto

Noldorin Points 67794

Je pense que tu viens de résumer les avantages tout à fait bien. Vous êtes cependant il manque un point. L' decimal type est seulement plus précis à la représentation en base 10 des nombres (par exemple ceux de monnaie/calculs financiers). En général, l' double type va offrir au moins aussi grande précision (quelqu'un me corrige si je me trompe) et certainement une plus grande vitesse pour arbitraire des nombres réels. La conclusion est simple: lorsque l'on envisage de l'utiliser, utilisez toujours de l' double , sauf si vous avez besoin de l' base 10 précision decimal offre.

Edit:

Concernant votre question supplémentaire à propos de la diminution de la précision des nombres à virgule flottante après les opérations, c'est un peu plus subtile question. En effet, la précision (j'utilise ce terme de façon interchangeable pour plus de précision ici) va diminuer régulièrement après chaque opération est effectuée. Cela est dû à deux raisons: a) le fait que certains numéros (le plus évident de décimales) ne peut pas être réellement représentés en virgule flottante, b) les erreurs d'arrondi se produire, comme si vous faisiez le calcul à la main. Cela dépend beaucoup du contexte (le nombre d'opérations que vous effectuez) si ces erreurs sont suffisamment importants pour justifier beaucoup de pensée. Dans tous les cas, si vous voulez comparer deux nombres à virgule flottante qui devrait en théorie être équivalent (mais on est parvenu à l'aide de différents calculs de), vous devez autoriser un certain degré de tolérance (combien varie, mais est généralement très petits).

Pour une présentation plus détaillée des cas particuliers où des erreurs de précision peut être introduit, voir la Précision de la section de l' article de Wikipédia. Enfin, si vous voulez sérieusement en profondeur (et mathématique) discussion des nombres à virgule flottante/opérations au niveau des machines, essayez de lire l'article souvent cité , Ce que Tout informaticien Devez Savoir à Propos de l'Arithmétique à virgule Flottante.

61voto

Michael Meadows Points 15277

Vous semblez sur place avec les avantages de l'utilisation d'un type à virgule flottante. J'ai tendance à concevoir pour les décimales dans tous les cas, et s'appuient sur un profileur de me laisser savoir si les opérations sur les décimaux est à l'origine des goulots d'étranglement ou les ralentissements. Dans ces cas, je vais "en bas" jeté de lit double ou float, mais seulement le faire en interne, et soigneusement essayer de gérer la perte de précision due en limitant le nombre de chiffres significatifs dans l'opération mathématique à effectuer.

En général, si votre valeur est transitoire (pas réutilisé), vous êtes sûr d'utiliser un type à virgule flottante. Le vrai problème avec virgule flottante types est la suivante pour les trois scénarios.

  1. Vous l'agrégation des valeurs à virgule flottante (dans ce cas, les erreurs de précision composé)
  2. Vous construisez des valeurs basées sur la valeur à virgule flottante (par exemple dans un algorithme récursif)
  3. Vous êtes à faire des mathématiques avec un très grand nombre de chiffres significatifs (par exemple, 123456789.1 * .000000000000000987654321)

MODIFIER

Selon la documentation de référence sur le C# décimales:

La virgule mot-clé indique un 128-bits type de données. Par rapport à les types à virgule flottante, le type décimal a une plus grande précision et une plus petite la gamme, qui le rend approprié pour monétaire et financier calculs.

Donc, pour clarifier ma déclaration ci-dessus:

J'ai tendance à concevoir pour les décimales dans tous les cas, et de s'appuyer sur un profileur de laisser - moi savoir si les opérations sur les décimaux est provoquent des goulots d'étranglement ou les ralentissements.

Je n'ai jamais travaillé dans les industries où les décimales sont favorables. Si vous travaillez sur phsyics ou les moteurs graphiques, il est probablement beaucoup plus bénéfique pour la conception d'un type à virgule flottante (float ou double).

Virgule n'est pas infiniment précis (il est impossible de représenter une précision infinie pour les non-intégré dans un type de données primitif), mais il est beaucoup plus précis que le double:

  • décimal = 28-29 chiffres significatifs
  • double = 15 et 16 chiffres significatifs
  • float = 7 chiffres significatifs

EDIT 2

En réponse à Konrad Rudolph's commentaire, le point n ° 1 (ci-dessus) est certainement correct. L'agrégation de l'imprécision n'est en effet composé. Voir le code ci-dessous pour un exemple:

private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;

public static void Main(string[] args)
{
    Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
    float asSingle = 0f;
    double asDouble = 0d;
    decimal asDecimal = 0M;

    for (int i = 0; i < ONE_MILLION; i++)
    {
        asSingle += THREE_FIFTHS;
        asDouble += THREE_FIFTHS;
        asDecimal += (decimal) THREE_FIFTHS;
    }
    Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
    Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
    Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
    Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
    Console.ReadLine();
}

Ce résultats suivants:

Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000

Comme vous pouvez le voir, même si nous ajoutons à partir de la même source constante, les résultats de la double est moins précis (bien que probablement va s'arrondir correctement), et le flotteur est beaucoup moins précis, au point où il a été réduit à seulement deux chiffres significatifs.

26voto

Joe Points 60749

Utiliser la virgule pour la base de 10 valeurs, par exemple les calculs financiers, comme d'autres l'ont suggéré.

Mais le double est généralement plus précis, pour arbitraire des valeurs calculées.

Par exemple, si vous souhaitez calculer le poids de chaque ligne dans un portefeuille, utilisez le double que le résultat sera plus près de 100%.

Dans l'exemple suivant, doubleResult est plus proche de 1 que decimalResult:

// Add one third + one third + one third with decimal
decimal decimalValue = 1M / 3M;
decimal decimalResult = decimalValue + decimalValue + decimalValue;
// Add one third + one third + one third with double
double doubleValue = 1D / 3D;
double doubleResult = doubleValue + doubleValue + doubleValue;

Donc encore une fois en prenant l'exemple d'un portefeuille:

  • La valeur de marché de chaque ligne dans le portefeuille d'une valeur monétaire et le mieux serait peut-être représenté comme séparateur décimal.

  • Le poids de chaque ligne du portefeuille (= Valeur de Marché / SOMME(Valeur de Marché)) est généralement représenté comme un double.

6voto

FlySwat Points 61945

Utiliser 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 de joueur. Évidemment je ne besoin de super précision ici parce que j’ai finalement rond en Int pour dessiner à l’écran.

3voto

Will Dean Points 25866

Si vous devez interrop binaire avec d’autres langues ou plates-formes, alors vous devrez utiliser float ou double, qui sont normalisés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X