Aller au contenu principal

Le codage en binaire des nombres non entiers

Le principe est l'extension du système déjà rencontré pour les nombres entiers. La partie décimale (à droite de la virgule) correspondra aux puissances négatives de 2.

...84210.50.250.125...
...232^3222^2212^1202^0212^{-1}222^{-2}232^{-3}...
...0110,101...

Exemple : 110,1012=1×22+1×21+0×20+1×21+0×22+1×22=4+2+0,5+0,125=6,625110,101_2=1 \times 2^2 + 1 \times2^1 +0 \times 2^0 + 1 \times 2^{-1} +0 \times 2^{-2}+1 \times 2^{-2} =4+2+0,5+0,125=6,625

Tentatives de conversion

Tout commence bien, avec un résultat mathématique rassurant : tous les nombres réels peuvent s'écrire comme une somme de puissances de 2 (puissances positives et négatives).

Théorème :

Pour tout réel xR+x \in \mathbb{R}^+, il existe pNp \in \mathbb{N} et (ap,ap1,...,a0,a1,a2,...)(a_p,a_{p-1},...,a_0,a_{-1},a_{-2},...) tels que x=i=0pai2i+i=1+ai2ix = \sum_{i=0}^pa_i2^i+\sum_{i=1}^{+\infty}a_{-i}2^{-i}

Écrire un nombre en binaire revient à calculer les coefficients aka_k (ils sont égaux à 0 ou 1). Il y en a un nombre fini pour la partie entière, mais un nombre potentiellement infini pour la partie décimale.

Méthode de conversion

Considérons le nombre 3,68753,6875. Il se décompose en une partie entière (3) et une partie décimale (0,68750,6875).

  • partie entière : 3=1123=11_2
  • partie entière : la conversion de 0,68750,6875 se fait en plusieurs étapes.
    0,6875×2=1,3750,6875 \times 2 = \textbf{1},375
    0,375×2=0,750,375 \times 2 = \textbf{0},75
    0,75×2=1,50,75 \times 2 = \textbf{1},5
    0,5×2=10,5 \times 2 = \textbf{1}

On prend ensuite le chiffre des unités de tous les nombres obtenus : 1011

Donc 3,6875=11,101123,6875=11,1011_2

Exercice 1

Donner l'écriture binaire de 20,875.

correction :

  • partie entière : 20=10100220 = 10100_2
  • partie décimale :
    • 0,875×2=1,750,875 \times 2 = \textbf{1},75
    • 0,75×2=1,50,75 \times 2 = \textbf{1},5
    • 0,5×2=10,5 \times 2 = \textbf{1}

Donc 20,875=10100,111220,875=10100,111_2

Exercice 2

Donner l'écriture binaire de 0,2.

correction :

  • partie entière : 0=020 = 0_2
  • partie décimale :
    • 0,2×2=0,40,2 \times 2 = \textbf{0},4
    • 0,4×2=0,80,4 \times 2 = \textbf{0},8
    • 0,8×2=1,60,8 \times 2 = \textbf{1},6
    • 0,6×2=1,20,6 \times 2 = \textbf{1},2
    • 0,2×2=0,40,2 \times 2 = \textbf{0},4
    • et cela continue...

Le nombre 0,2 n'admet pas d'écriture binaire finie.

Conclusion

Certains nombres n'admettent pas une écriture binaire finie. Or la mémoire d'un ordinateur, quelqu'il soit, est toujours finie. Certains nombres ne peuvent donc pas être représentés correctement en machine : c'est une impossibilité théorique. Cela amène à des comportements étranges :

0.1+0.2
# 0.30000000000000004

Conséquences : la difficile manipulation des flottants

En python, les nombres non entiers sont du type float.

type(0.1)
# float

Ces flottants (traduction française) sont à manipuler avec une extrême précaution. Il faut garder en tête que les calculs sont potentiellement faux, du moins imprécis, lorsque des flottants interviennent.

info

En 1991, durant la Guerre du Golfe, un missile anti-missile américain a raté sa cible de 500 mètres car son ordinateur interne émettait un signal toutes les 0.1 secondes. Au bout de 100 heures de fonctionnement, l'approximation du nombre flottant 0.1 a conduit à un décalage de 0,34 secondes, ce qui lui a fait rater sa cible. (source)