69 votes

Un double est-il vraiment impropre à l'argent?

Je dis toujours en c# une variable de type double n'est pas adapté pour de l'argent. Toutes les choses bizarres qui peuvent arriver. Mais je n'arrive pas à créer un exemple pour démontrer certaines de ces questions. Quelqu'un peut fournir un tel exemple?

(edit; ce billet a été initialement marqués C#; certaines réponses se référer pour les détails spécifiques de decimal, ce qui signifie par conséquent System.Decimal).

(edit 2: j'ai été spécifiques demandant un code c#, donc je ne pense pas que ce soit la langue agnostique seulement)

114voto

Marc Gravell Points 482669

Très, très inadapté. Utilisez décimal.

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

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

34voto

Jon Skeet Points 692016

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

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
    }
}
 

7voto

Mendelt Points 21583

Oui, il ne convient pas.

Si je me souviens bien double a environ 17 grand nombre, et donc, normalement, les erreurs d'arrondi aura lieu loin derrière le point décimal. La plupart des logiciels financiers utilise 4 décimales derrière la virgule, qui laisse 13 décimales de travailler avec de sorte que le nombre maximum que l'on peut travailler avec pour unique des opérations est encore beaucoup plus élevé que les états-unis de la dette nationale. Mais les erreurs d'arrondi sera ajouter jusqu'à plus d'heure. Si votre logiciel ne s'exécute pendant une longue période, vous allez commencer à perdre cents. Certaines opérations vont aggraver la situation. Par exemple, en ajoutant de grandes quantités de petites quantités sera la cause d'une perte importante de précision.

Vous avez besoin de point fixe de types de données pour les opérations monétaires, la plupart des gens ne me dérange pas si vous perdez un cent d'ici et 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 Doubles disposent effectivement de 15 à 16 chiffres significatifs au lieu de 17.

@Jon Skeet décimal est plus adapté qu'un double en raison de sa plus grande précision, le 28 ou le 29 significative des décimales. Cela signifie moins de chance de l'accumulation des erreurs d'arrondi de plus en plus élevés. Point fixe de types de données (c'est à dire des entiers qui représentent cents ou 100e d'un cent que j'ai vu utilisé) comme Boojum mentionne sont effectivement les mieux adaptés.

5voto

Richard Poole Points 2410

Puisque decimal utilise un facteur de mise à l'échelle de multiples de 10, des nombres tels que 0,1 peuvent être représentés exactement. Essentiellement, le type décimal représente cela comme 1/10 ^ 1, alors qu'un double représenterait cela comme 104857/2 ^ 20 (en réalité, ce serait plutôt comme un très grand nombre / 2 ^ 1023 ).

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

4voto

Boojum Points 4688

D'après ce que je comprends, la plupart des systèmes financiers expriment des devises à l'aide d'entiers, c'est-à-dire qu'ils comptent tout en cents.

La double précision IEEE peut en fait représenter tous les nombres entiers dans une 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 constater aucune perte de précision. Je me méfierais cependant beaucoup des divisions ou des opérations plus complexes.

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