Question

Je dis toujours en c # une variable de type double ne convient pas à money. Toutes les choses étranges pourraient arriver. Mais je n'arrive pas à créer un exemple pour illustrer certains de ces problèmes. Quelqu'un peut-il fournir un tel exemple?

(edit; cet article a été à l'origine étiqueté C #; certaines réponses font référence à des détails spécifiques sur décimal , ce qui signifie donc System.Decimal ).

(2e édition: je demandais spécifiquement un code c #, donc je ne pense pas que ce soit une langue agnostique uniquement)

Était-ce utile?

La solution

Très, très inadapté. Utilisez des décimales.

double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false

(exemple tiré de la page de de Jon - lecture recommandée ;-p)

Autres conseils

Vous obtiendrez effectivement des erreurs étranges causées par l’arrondi. En outre, les comparaisons avec les valeurs exactes sont extrêmement délicates - vous devez généralement appliquer une sorte d’epsilon pour vérifier si la valeur réelle est "proche de". un particulier.

Voici un exemple concret:

using System;

class Test
{
    static void Main()
    {
        double x = 0.1;
        double y = x + x + x;
        Console.WriteLine(y == 0.3); // Prints False
    }
}

Oui, cela ne convient pas.

Si je me souviens bien, le double a environ 17 chiffres significatifs. Les erreurs d’arrondi se dérouleront donc loin derrière la virgule décimale. La plupart des logiciels financiers utilisent 4 décimales derrière la virgule, ce qui laisse 13 décimales à utiliser, de sorte que le nombre maximal avec lequel vous pouvez travailler pour des opérations uniques est encore beaucoup plus élevé que la dette nationale des États-Unis. Mais les erreurs d'arrondi vont s'accumuler avec le temps. Si votre logiciel fonctionne longtemps, vous finirez par perdre des sous. Certaines opérations aggraveront la situation. Par exemple, ajouter de grandes quantités à de petites quantités entraînera une perte de précision significative.

Vous avez besoin de types de données à points fixes pour les opérations monétaires, la plupart des gens ne voient pas d'inconvénient à perdre un cent ici ou là, mais les comptables ne sont pas comme la plupart des gens.

modifier
Selon ce site, http://msdn.microsoft.com/en-us/library /678hzkk9.aspx Les doubles ont en réalité 15 à 16 chiffres significatifs au lieu de 17.

@Jon La décimale Skeet convient mieux que double en raison de sa précision supérieure, 28 ou 29 décimales significatives. Cela signifie moins de chances que les erreurs d'arrondi accumulées deviennent significatives. Les types de données à point fixe (c'est-à-dire des entiers qui représentent des centimes ou centièmes comme ceux que j'ai vus utilisés), comme les mentions de Boojum, sont en réalité mieux adaptés.

Puisque decimal utilise un facteur d'échelle multiple de 10, les nombres tels que 0,1 peuvent être représentés exactement. Essentiellement, le type décimal représente ceci comme 1/10 ^ 1, alors qu'un double représenterait cela comme 104857/2 ^ 20 (en réalité, il s'agirait plus de vraiment-grand-nombre / 2 ^ 1023).

Un décimal peut représenter exactement toute valeur de base 10 comportant jusqu'à 28/29 chiffres significatifs (comme 0.1). Un double ne peut pas.

À ce que je sache, la plupart des systèmes financiers expriment les devises à l’aide de nombres entiers, c’est-à-dire qu’ils comptent tout en cents.

La

double précision IEEE peut réellement représenter tous les entiers dans la plage allant de -2 ^ 53 à + 2 ^ 53. (Hacker's Delight, p. 262) Si vous n'utilisez que des additions, des soustractions et des multiplications et que vous conservez le tout sous forme de nombres entiers compris dans cette plage, vous ne devriez voir aucune perte de précision. Je me méfierais cependant beaucoup de la division ou d'opérations plus complexes.

L'utilisation de double lorsque vous ne savez pas ce que vous faites est inappropriée.

" double " peut représenter un montant d'un billion de dollars avec une erreur de 1 / 90ème de cent. Donc, vous obtiendrez des résultats très précis. Vous voulez calculer combien il en coûte pour mettre un homme sur Mars et le ramener vivant? double fera très bien l'affaire.

Mais avec de l’argent, il existe souvent des règles très précises selon lesquelles un certain calcul doit donner un résultat donné et aucun autre. Si vous calculez un montant très très proche de 98,135 $, il y aura souvent une règle qui déterminera si le résultat doit être de 98,14 $ ou 98,13 $ et vous devez suivre cette règle et obtenir le résultat requis. .

Selon votre lieu de résidence, l'utilisation d'entiers 64 bits pour représenter des centimes, des centimes ou des kopecks ou toute autre unité représentant la plus petite unité de votre pays fonctionnera généralement très bien. Par exemple, des entiers signés sur 64 bits représentant des cents peuvent représenter des valeurs allant jusqu'à 92 223 milliards de dollars. Les entiers 32 bits ne conviennent généralement pas.

Non, un double aura toujours des erreurs d'arrondi, utilisez " décimal " si vous êtes sur .Net ...

En réalité, le double à virgule flottante convient parfaitement à la représentation de montants d'argent tant que vous choisissez une unité appropriée.

Voir http://www.idinews.com/moneyRep.html

Ainsi, le point fixe long . Consomme 8 octets, ce qui est certainement préférable aux 16 consommés par un élément décimal .

Que quelque chose fonctionne ou non (c’est-à-dire qui donne le résultat attendu et correct) n’est pas une question de vote ni de préférence individuelle. Une technique fonctionne ou non.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top