Esse que votre ordinateur est vraiment bon en calcul ?

Oui évidemment. Mais le fait que celui-ci fasse ses calculs avec des 0 et des 1 amène certains paradoxes intéressants. Un exemple:
Normalement en math on s’attendrait a ce qu’une simple formule comme la suivante se vérifie toujours:
x = b * (x * 1/b)

(l'étoile est une multiplication)
Cependant avec certains chiffres qui sembles inoffensifs quand on fait les calculs sur l'ordinateur, on obtient parfois des résultats surprenants. Prenons 10 par exemple. Voilà un nombre qui semble inoffensif alors on pourrait s'attendre à ce que 1/10 le soit également, mais faisons un test. Pour faire le test je vais utiliser dans un premier temps un truc qui se nomme un REPL pour "Read Eval Print Loop". Donc un truc qui lit des expressions dans un langage de programmation et qui exécute et affiche le résultat. Dans ce cas-ci j'utilise une REPL basé sur Python. L'exemple va comme ceci:

In [15]: one_tenth = 1.0 / 10.0

In [16]: 10 * (one_tenth * 123456789123456)
Out[16]: 123456789123456.02

Tiens, tiens. Qu'esse qui se passe ?
Certains vont penser que le problème vient de la combinaison d'un gros chiffre avec un petit chiffre, mais non ce n'est pas ça le problème. Le gros chiffre n'a rien de vraiment spécial sinon d'être assez grand pour faire sortir le problème avec 1/10. Le problème, c'est 1/10. Le problème, c'est que votre ordinateur n'est pas capable de représenter exactement 1/10 directement dans le format qu'il utilise pour faire des calculs. La preuve (pas complètement rigoureuse - mais on va compléter avec d'autres éléments.) c'est qu'on peut cerner 1/10 avec une fraction plus petite et une fraction plus grande qui ne font pas le problème:

In [17]: one_16th = 1.0 / 16.0

In [18]: 16 * (one_16th * 123456789123456)
Out[18]: 123456789123456.0

In [20]: one_8th = 1.0 / 8.0

In [21]: 8 * (one_8th * 123456789123456)
Out[21]: 123456789123456.0


L'explication vient du fait que, comme mentionné au début, votre ordinateur fait toutes ses opérations avec uniquement des 0 et des 1 qui représente des puissances de 2. Pour les chiffres entiers pas de problème, car tous les chiffres entiers peuvent se représenté comme la somme d'une série de puissance de 2. En pratique, il y a une limite au niveau de la valeur maximale que l'ordinateur peut représenter sans erreur, mais ce problème se présente seulement avec de très gros chiffres et en théorie, on pourrait toujours ajouter des bits et représenté n'importe quel chiffre entier exactement. Cependant pour les fractions ça ne fonctionne pas aussi bien même pour de fractions qui ne semblent pas particulières (très petites par exemple). Pour la partie fractionnaire d'un nombre, l'ordinateur utilise une suite de puissances négatives de 2 et cette suite ne donne pas toujours le résultat exacte dans l'espace réservé pour représenter un nombre dans votre ordinateur et dans le cas de certaines fractions comme 1/10 le résultat serait toujours une approximation même si on ajoutait des bits parce que 1/10 ne peut être représenté par une série finie de puissance négative de deux. Dans le cas de notre fraction l'ordinateur démarre comme ceci:
In [6]: 1.0/16.0 + 1.0/32.0 + 1.0 / 64.0
Out[6]: 0.109375

Oups,trop gros alors il ajuste le tir et après quelques essais il continue:

In [9]: 1.0/16.0 + 1.0/32.0 + 0.0 + 0.0 + 1.0 / 256.0
Out[9]: 0.09765625


Donc : 1 x 2^-4 + 1 x 2^-5 + 0 x 2^-6 + 0 x 2^-7 + 1 x 2^-8 ...
Il finit pas trouvé:

110011001100110011001101

La dernière séquence de 2 bits à la fin représente l'arrondi que l'ordinateur choisis de faire parce que la séquence de 1100 1100 continue au-delà de l'espace disponible. Il arrondit par en haut, d'ou l'erreur quand on utilise l'équation de départ avec 1/10.
Vous auriez les mêmes erreurs dans Excel si vous affichez toutes les décimal mais il faudrait probablement utiliser de plus gros chiffres car Excel utilise plus de précision par défaut. Mais ça change rien au patron de bits généré pour 1/10.

Comments

Popular posts from this blog

Spinoza pour les non-théistes