Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

Considérations sur la comparaison de valeurs numériques stockées sous forme de double

0000002680     -      06/01/2017

Le double est un type permettant le stockage d'une valeur numérique sous forme binaire avec virgule flottante.(Binary floating point) Cela signifie que chaque "nombre" stocké sous cette forme n'est pas représenté de façon unique. Dès lors, comparer deux doubles de façon brute peut donner des résultats erronés.

Par exemple, ce test renvoie false :

Zoom
double x1 = 43.65 + 61.11;
double x2 = 104.76;
bool test = (x1 == x2);

simplement parce que la représentation de x1 est 104.75999999999999.

Pour contrer ce problème, il faut prendre en compte un nombre de décimales significatives pour effectuer la comparaison. Cela peut être effectué grâce à l'extension du type Double apportée par MercatorExtensions. Cette extension offre une méthode Compare qui permet de passer en second paramètre le nombre de décimales à prendre en compte pour la comparaison.

Ainsi, le même exemple que celui indiqué ci-dessus, effectué sur 2 décimales, renvoie à présent bien true :

Zoom
double x1 = 43.65 + 61.11;
double x2 = 104.76;
bool test = (x1.CompareTo(x2, 2) == 0);

 

De façon classique, la méthode Compare renvoie :

  • 1 si x1 est supérieur à x2
  • 0 si x1 est égal à x2
  • -1 si x1 est inférieur à x2

Pour pouvoir utiliser cette extension, il faut ajouter la clause using MercatorExtensions; en haut de votre code. (Cette clause s'ajoute automatiquement dans l'éditeur de code de Mercator)

Note : la méthode Compare, sans le second paramètre, est celle qui est native dans le framework .net. Elle renverra malheureusement le même résultat que le premier exemple de cette page. Il faut donc bien veiller à utiliser la méthode avec 2 paramètres.

Selon la fonctionnalité où doit prendre place ce type de code, il faut choisir le nombre de décimales à prendre en considération dans ce contexte :

  • billingEngine.NDec : nombre de décimales des totaux dans la devise du document de la gestion commerciale
  • billingEngine.NDecPu : nombre de décimales des prix unitaires dans la devise du document de la gestion commerciale
  • bookingEngine.NDec : nombre de décimales pour la devise de l'écriture comptable
  • MercatorUi.Globals.N_DEC_P : nombre de décimales des poids
  • MercatorUi.Globals.N_DEC_Q : nombre de décimales des quantités
  • MercatorUi.Globals.DEC_DEV_B : nombre de décimales devise de base pour la gestion commerciale
  • MercatorUi.Globals.DEC_DEV_C : nombre de décimales devise de base en comptabilité