Dans un projet console, amusez-vous à écrire le code suivant :
Console.WriteLine(Math.Round(3.135, 2));
Vous obtiendrez la résultat suivant :
Quelle horreur… ! Au delà de ma déception, l’impact peut-être grave dans vos processus métier : facturation, devis, mise sur orbite d’un satellite… 🙂
Microsoft explique ce défaut à cause d’une perte de précision qui résulte de la représentation des valeurs décimales sous la forme de nombres à virgule flottante. L’algorithme interne utiliserais une multiplication qui soufrerais d’une perte de précision.
De ce constant il suffit de ne plus utiliser les méthodes surchargées qui prennent en paramètre les types System.Double, mais d’utiliser celles qui prennent des types System.Decimal comme le code suivant :
Console.WriteLine(Math.Round(3.135m, 2));
Qui nous donne le résultat souhaité :
Notez que je n’utilise pas l’opérateur de casting mais directement une valeur de type System.Decimal. Si vous désirez qu’un littéral soit considéré comme tel, utilisez le suffixe m (ou M), de même que le suffixe d pour un type System.Double, f pour un type System.Float, L pour un type System.Int64 et finalement le préfixe u pour les type non-signés.
Je trouve que la remarque dans la documentation MSDN n’est pas des plus idéale, j’aurais préféré que les surcharges qui prennent en paramètre les types System.Double n’existent tout simplement pas…
Le problème est en fait très complexe, même si l’on ne s’en rend pas compte, traiter des nombres décimaux par des ordinateurs a toujours été une prouesse, surtout lorsqu’un nombre a une infinité de décimaux, c’est comme demander à un humain d’écrire le nombre π, ou même 1/3, c’est aussi compliqué que çà !
L’exemple par la preuve :
Donne le résultat suivant :
Que le code suivant corrige :
Pourtant la même opération avec des types System.Double donne directement le bon résultat (1) !!!
En réalité tout dépend de la représentation en mémoire de la valeur et de la perte de précision de l’opération. Retenons simplement que lorsque nous devrons gérer des nombres décimaux, nous resterons vigilant car il n’y a rien de si naturel à cela !
oh branleur ! ca post pas des masses 🙂
Ton commentaire n’a aucun intérêt. Ah moins de vouloir m’indiquer qu’il n’y a pas que les décimaux qui sont fourbes ! 😉
Vincent il a raison, ça bosse pas des masses ici!!!!
Je t’ai connu plus inspiré
Si tu savais mon vieil ami, à nous deux on fabriquerait un .NET9, tous « neuf » et sans bavure…
Perso, pas le temps de bloguer, et j’en suis le premier fautif je le sais ! Mais que Veux-tu, dès que j’en apprends plus, au lieu de partager je passe à l’étape suivante pour faire des projets perso. Celui du moment est une application sur le projet open-source domoticz.
C’est vrai que c’est dommage car je pourrais en dire des masses et le « welcome » de mon blog ne prétendait pas à si peu de contenu, mais je préfère m’épanouir comme çà ; pour le moment en tous les cas !
Je suis content que de ton côté, tu es repris ton blog, qui est aussi pragmatique que de bonne qualité !
Au plaisir Monsieur le chimiste 😉