C’était un article passionnant dont je voulais parler il y a déjà longtemps : An introduction to different rounding algorithms.

On rappelle qu’en ingénierie (donc dans le monde réel auquel le résultat d’un programme se confronte fatalement un jour), un nombre comme 4,0 est forcément associé à un degré de précision exprimé par le nombre de chiffres : ici, deux chiffres significatifs impliquent une valeur entre 3,9 et 4,1.

En comptabilité, les nombres sont en général fixes : 3,56 € est implicitement strictement équivalent à 3,56 ± 0,0000000000000000000000000000000... € aussi précisément qu’est défini π. Et 200 €, c’est également 200,0000000000000000000000000000000000000000000000... €. Même la manipulation des quantités (addition, multiplication...) ne pose pas de problème, parce que la division d’une somme de 3 € en dix ne donnera jamais naissance à des tiers de centime, mais quelque part quelqu’un prendra ou supprimera ce centime. Idem dans les transactions de devises, on se contente d’échanger des yens contre des euros, qui existent déjà, avec un nombre décimales fixes. J’ai vu des prix fixés en dollars avec six décimales[1] mais le prix final, lui, produit d’une multiplication, était arrondi : on n’ergote pas sur un dixième de centime quand la somme finale se chiffre en centaine de milliers.

Les comptables ont plus sué (et les consultants ont gagné pas mal de sous) lors du passage à l’euro ; là pas d’échange de devises, mais une conversion de la monnaie en une autre avec un taux pas simple du tout[2], et la garantie que la conversion des francs/marks/pesetas/florins/lires/schillings... en euros ne tomberait pas souvent juste. Ce fut une orgie de comptes destinés à récupérer des minuscules erreurs d’arrondis (calculés à quel niveau ? sur quels totaux ou sous-totaux ?), et je suis fort aise de ne pas avoir touché à la compta à cette époque.

Il n’empêche que dans tous les cas il faut arrondir. Si dans les transactions commerciales de tous les jours on arrondit en général vers le bas ou au plus proche ou à la tête du client sans se poser de questions, le jeu devient plus délicat pour les ingénieurs et quelques comptables qui ne veulent pas voir s’accumuler des approximations dues à ces arrondis, surtout dans les opérations répétitives.

Avec un chiffre significatif, on arrondit 3,1 à 3, et 3,8 à 4, mais quid de 3,5 situé à mi-chemin entre 3 et 4 ? En général on décide d’arrondir à l’inférieur (les cinq premières valeurs après le 3 arrondies au 3, les cinq suivantes au 4), ce qui donne 3. Mais pour être cohérent il faudrait arrondir -3,5 à -4, ce qui peut choquer. Même problème pour la technique d’arrondi au supérieur, et là aussi on risque un biais.

L’arrondi du banquier demande d’intervertir le sens d’arrondi alternativement pour la valeur « du milieu » : 3,1 arrondi à 3, 3,5 arrondi à 4, 4,5 arrondi à 4, et 5,5 arrondi à 6. Là aussi, il y a risque de biais si les valeurs penchent pour une parité particulière.

L’arrondi stochastique choisit de façon aléatoire 3 ou 4 pour arrondir 3,5. Franchement, calculer en n’étant pas certain d’avoir deux fois le même résultat me rend très dubitatif...

Les fonctions floor (sol) et ceil (plafond) souvent rencontrées se contrefichent de la valeur de la mantisse : 3,1 comme 3,9 s’arrondissent en 3 avec floor, et en 4 avec ceil (et -3,1 respectivement en -4 et -3). Ils introduisent donc un biais, mais cela n’a pas forcément d’importance.

L’arrondi vers le zéro utilise floor pour les nombres positifs, ceil pour les négatifs pour supprimer les biais.

La pure suppression de la mantisse (chopping) semble simple mais peut générer de sulfureux problèmes selon les objets informatiques réels que l’on manipule.

En deuxième partie, l’article s’étend sur les considérations très techniques, notamment si c’est du matériel simple, et non un processeur surdopé aux gigahertz, qui doit effectuer le travail.

J’ajouterai que limiter les erreurs d’arrondis est un but souvent suffisant, mais les supprimer est illusoire. En conséquence, en calcul numérique, comparer deux valeurs qui n’ont pas implicitement une précision exacte (comme de la monnaie ou un entier stocké sous forme d’integer) relève de la roulette russe, puisqu’à cause de l’arrondi le bête ordinateur risque de ne pas voir que le 9,999999999999999999 qu’il a calculé n’est pas égal à 10 (sous-entendu 10,0000000000000...). Il faut alors définir un seuil de tolérance ε (par exemple 0,000000000001) en-dessous duquel on estimera que la différence entre les deux chiffres est du bruit, et qu’il sont égaux.

Personnellement, je reste parfois rêveur devant des rapports Business Objects qui se limitent à des sommations et soustractions, mais affichent 0,00 sur une ligne, et -0,00 sur la suivante.

Par contre, les non-arrondis parfois bien nécessaires me font hurler : un institut de sondage sort par exemple un nombre de deux chiffres significatifs calculé à partir d’une poignée de personnes alors que la précision est plutôt de l’ordre du chiffre unique. Mais parler de « 57% des Français » fait plus sérieux que « 50% à 10 points près ». Voir par exemple une célèbre étude sur la composition démographique de l’électorat de Sarkozy, dont j’avais parlé ici.

En informatique de gestion, on apprend bien vite que les nombres ne sont pas les seuls à s’arrondir. La première fois que l’on calcule TRUNC(une_date) (dans mon cas avec Oracle) cela surprend, mais on s’y fait très vite : sous Oracle, un jour s’identifie à un entier. Le tronquer (supprimer la mantisse) revient à en prendre le début à minuit. Et on obtient le premier janvier de l’année avec TRUNC(une_date,'YYYY').

Qu’une opération aussi basique que l’arrondi puisse donner lieu parfois à d’énormes prises de têtes me fascinera toujours. Der Teufel steckt im Detail.

Notes

[1] Pour chiffrer ce qui passait à la sortie d’un pipeline.

[2] Quoique le facteur de conversion français de 6,55957 ne pose ni plus ni moins de problème que le 1,95583 allemand, qui ne s’arrondit que psychologiquement à 2, pas comptablement.