August 19, 2009
L'informatique, les nombres et les arrondis
Devinette: qu'affiche le bout de code c suivant:double v=847.665000;
printf("v=%.2f\n",v)
Vous avez dit 847.67 ? Perdu, c'est 847.66
Tout simplement parce que:
printf("v32=%.32f\n",v);
révèle qu'en fait v vaut a peu pres: 847.66499999999996362021192908287048
Plus étonnant:
printf("%.32f\n", 1.25);
donne 1.25000000000000000000000000000000
mais printf("%.1f\n", 1.25);
donne 1.2 alors que
printf("%.32f\n", 1.75);
donne 1.75000000000000000000000000000000
et printf("%.1f\n", 1.75);
donne 1.8
Je repete: 1.25 donne 1.2 mais 1.75 donne 1.8
Etrange, non ? Et bien la c'est "tout simplement" que printf utilise non pas un arrondi arithmétique mais un arrondi "au pair le plus proche" (nommé aussi "arrondi bancaire").
Détail amusant, la fonction round() n'arrondi pas pareil, il utilise un arrondi "to nearest integer, halfway away from zero", c'est a dire que
round(1.25*10)/10 donne a peu pres 1.3 (la ou printf donnerais 1.2)
et round(1.75*10)/10 donne a peu pres 1.8
Je suis tombé des nues en voyant comment printf arrondissait: en plus de 20 ans de développement, je n'avais jamais jamais suscpecté qu'il pouvait arrondir avec une méthode différente de l'arrondi arithmétique.
Et le pire c'est que round() produit un résultat different selon le language (voir la version du language): Cf Wikipedia EN: Rounding
Références:
A Question Of Rounding
Wikipedia FR: Arrondi
Wikipedia EN: Rounding
Posted 9 years, 5 months ago on August 19, 2009
The trackback url for this post is http://mguesdon.oxymium.net/blog/bblog/trackback.php/144/
The trackback url for this post is http://mguesdon.oxymium.net/blog/bblog/trackback.php/144/
Comments have now been turned off for this post