Des écritures qui ne se terminent pas☘
Écriture décimale avec une infinité de chiffres☘
Les nombres réels non décimaux ont une écriture décimale avec une infinité de chiffres après la virgule.
C'est le cas de \pi, \sqrt{2}, \frac{1}{3} par exemple.
Ces nombres réels auront nécessairement aussi une écriture en base deux avec une infinité de décimales.
La conséquence est que tous ces nombres ne peuvent pas être représentés (de manière exacte) par des flottants puisque par nature un nombre en machine ne présente qu'un nombre fini de chiffres.
Écriture décimale finie☘
Mais le problème ne s'arrête pas là: il existe également des nombres qui sont décimaux (donc ont une écriture décimale présentant un nombre fini de chiffres) mais qui n'ont pas un nombre fini de chiffres en base 2.
Ces nombres ne peuvent donc pas non plus être représentés de façon exacte en machine.
Un dixième en binaire☘
Donner l'écriture en base deux du nombre a = 0,1.
Réponse
- 0,1 × 2 = 0,2 = 0 + 0,2
- 0,2 × 2 = 0,4 = 0 + 0,4
- 0,4 × 2 = 0,8 = 0 + 0,8
- 0,8 × 2 = 1,6 = 1 + 0,6
- 0,6 × 2 = 1,2 = 1 + 0,2
- 0,2 × 2 = 0,4 = 0 + 0,4
- 0,4 × 2 = 0,8 = 0 + 0,8
- 0,8 × 2 = 1,6 = 1 + 0,6
- 0,6 × 2 = 1,2 = 1 + 0,2
A ce stade, on voit que l'on retombe sur 0,2: on va donc nécessairement réécrire les mêmes lignes que précédemment. Et on retombera ensuite sur 0,4 puis 0,8 puis sur 0,6 puis à nouveau sur 0,2.
On va ainsi boucler indéfiniment.
Ainsi 0,1 = 0,0 0011 0011 0011 0011... 2 où la séquence 0011 se répète inddéfiniment.
On a ainsi explicité un réel dont l'écriture décimale est finie (un seul chiffre après la virgule) mais dont l'écriture binaire présente une infinité de chiffres après la virgule.
Un tiers en binaire☘
Donner l'écriture binaire de \frac{1}{3}.
Réponse
- \frac{1}{3} \times 2 = \frac{2}{3} = 0 + \frac{2}{3} = 0 + 0.6666...
- \frac{2}{3} \times 2 = \frac{4}{3} = 1 + \frac{1}{3} = 1 + 0.3333...
- et on repart sur 1/3...
D'où l'écriture binaire de 1/3: 0, 01 01 01 01 01...2 où 01 se répète indéfiniment.
Conséquence☘
On voit avec l'exercice précédent que même avec un seul chiffre après la virgule en décimal, il peut y avoir une infinité de chiffres après la virgule en binaire.
On a donc déjà une clef essentielle pour comprendre le code:
>>> 0.2 + 0.1 == 0.3
False
Pour additionner 0.1 et 0.2, ces deux nombres sont d'abord traduit en base 2.
Comme 0.1 ne peut pas en fait être traduit de façon exacte en base 2 (puisqu'en machine, tout objet ne présente
qu'un nombre fini de 0 et de 1), on doit s'attendre à ce que des calculs faisant intervenir un tel nombre mène
à des erreurs dues à ce changement de base.
Remarque
Lorsqu'on entre 0.1, il est traduit en flottant en base deux.
Conséquence -- la demande de l'affichage de 0.1 avec 40 décimales
ne donne pas que des 0 (un arrondi a nécessairement lieu puisque
0.1 en binaire a une infinité de chiffres et qu'une machine n'en stocke
évidemment qu'un nombre fini)
>>> print("{:.40f}".format(0.1))
0.1000000000000000055511151231257827021182
On peut aussi utiliser le module decimal pour ce même constat:
>>> from decimal import Decimal
>>> Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
L'antimissile Patriot☘
Lors du conflit USA/Irak en 1991, les antimissiles Patriot (antimissiles américains) disposaient d'une horloge interne émettant un signal toutes les 0,1 seconde.
Le temps écoulé depuis le lancement de l'antimissile était obtenu en multipliant 0,1 par le nombre de signaux émis par l'horloge.
Lors d'une mission, l'un de ces antimissiles est passé à plus de 500m du missile qu'il devait intercepter provoquant indirectement la mort de 28 personnes.
- Pouvez-vous émettre une explication sur ce raté avec les seules données ci-dessus ?
Solution
La représentation de 0,1 en machine n'est pas exacte, comme nous l'avons déjà vu.
L'erreur entre la valeur réelle et la représentation en machine, multipliée par le grand nombre de signaux émis
lors d'un fonctionnement long conduit à un décalage.
Sur un fonctionnement d'une centaine d'heures, le décalage était d'environ 0,34 secondes. Ce qui, à la vitesse de
l'antimissile, conduit à un déplacement de plus de 500m.
Ce bug n'avait pas été détecté auparavant parce que le fonctionnement et notamment les tests utilisaient
des temps beaucoup plus courts.
- Avoir un signal d'horloge toutes les 0,125 s plutôt que toutes les 0,1 s améliorerait-il la situation ou la déteriorait-il ?
Solution
0,125 = \frac{1}{8} donc 0,125 s'écrit en base deux: 0,001deux. La représentation étant exacte, on n'aurait pas de décalage dû à une représentation non exacte. On aurait donc supprimé cette cause de dysfonctionnement.
Un article
Un extrait de wikipedia.
Le 25 février 1991, un Scud irakien frappait les casernes de Dhahran, en Arabie saoudite, tuant 28 soldats du centre de commandement du 14e détachement de l'armée des États-Unis.
Une recherche gouvernementale a indiqué que l'interception manquée de Dharan avait été provoquée par une erreur de logiciel dans son système de coordination. La batterie de missile Patriot de Dharan se trouvait alors en fonction depuis plus de 100 heures or, avec le temps, des erreurs apparaissaient dans le système et décalaient la position perçue de la cible avec sa position réelle. Sur ces 100 heures, l'erreur était proche d'une seconde, ce qui, à la vitesse très importante du missile, équivalait à un décalage de près de 600 mètres. Le système radar détecta bel et bien le Scud mais tous les missiles lancés le ratèrent inévitablement. Au début, on crut à un défaut de cette batterie et on la retira du service en moins d'une journée. La réalité était toute autre : les Israéliens avaient déjà identifié le problème et informé l'armée des États-Unis ainsi que le fabricant du logiciel de tir le 11 février 1991 mais aucune mise à niveau n'existait alors. On avait demandé à défaut d'autre chose aux commandants d'unités d'effectuer des réinitialisations régulières du système mais cette mesure avait dû se révéler insuffisante pour Dharan car les militaires n'en avaient pas compris l'utilité. Le fabricant parvint à fournir une mise à jour le 26, un jour trop tard pour les 28 militaires de Dharan.
un article plus technique
Vous pouvez lire cet article.