Les nombres réels⚓︎
I. Prérequis sur les puissances⚓︎
Question
- \(10^0=0\)
- \(10^0=1\)
- \(10^0=10\)
- \(10^0\) n'existe pas
-
\(10^0=0\) - \(10^0=1\)
-
\(10^0=10\) -
\(10^0\) n'existe pas
Question
- \(10^{-1}\) est négatif
- \(10^{-1}\) est positif
- \(10^{-1}\) est égal à 0
- \(10^{-1}\) n'existe pas
-
\(10^{-1}\) est négatif - \(10^{-1}\) est positif
-
\(10^{-1}\) est égal à 0 -
\(10^{-1}\) n'existe pas
Question
\(10^{-1}=\)?
- -1
- 0
- 1
- 10
- -0,1
- 0,1
-
-1 -
0 -
1 -
10 -
-0,1 - 0,1
Question
- \(2^0=0\)
- \(2^0=1\)
- \(2^0=2\)
- \(2^0\) n'existe pas
-
\(2^0=0\) - \(2^0=1\)
-
\(2^0=2\) -
\(2^0\) n'existe pas
Question
- \(2^{-1}\) est négatif
- \(2^{-1}\) est positif
- \(2^{-1}\) est égal à 0
- \(2^{-1}\) n'existe pas
-
\(2^{-1}\) est négatif - \(2^{-1}\) est positif
-
\(2^{-1}\) est égal à 0 -
\(2^{-1}\) n'existe pas
Question
\(2^{-1}=\)?
- -2
- 0
- 2
- 20
- 0,2
- 0,5
- - 0,5
-
-2 -
0 -
2 -
20 -
-0,2 - 0,5
-
-0,5
A retenir
Pour tout réel \(a\) et pour tout entier positif \(n\)
\(a^0=1\)
\(a^{-n}=\dfrac{1}{a^n}\)
Par exemple
- \(2^{-1}=\dfrac{1}{2^1}=0,5\)
- \(2^{-2}=\dfrac{1}{2^2}=0,25\)
II. Découverte des "float" ou "nombres flottants"⚓︎
Tester
Vive les entiers en Python !
Python nous donne la valeur exacte du résultat. 777 est un entier.
Tester
# Tests
(insensible à la casse)(Ctrl+I)
(Shift+Esc ; Ctrl pour inverser les colonnes)
(Esc)
Solution
777.0 n'est pas codé dans la machine comme un entier, mais comme un nombre flottant. Nous venons de constater que cela ne revient pas du tout au même !
Tester
# Tests
(insensible à la casse)(Ctrl+I)
(Shift+Esc ; Ctrl pour inverser les colonnes)
(Esc)
Echec
Nous devrons comprendre pourquoi \(0,1+0,2\) n'est pas égal à \(0,3\) pour Python. Ce n'est pas dû au langage Python, nous aurions le même problème avec d'autres langages.
Ce problème est dû à la façon dont les nombres à virgule appelés en français les flottants sont représentés dans la machine.
Une boucle while
Observez le code suivant. Que remarquez-vous ?
Solution
On est sur une boucle infinie
Tester
# Tests
(insensible à la casse)(Ctrl+I)
(Shift+Esc ; Ctrl pour inverser les colonnes)
(Esc)
Solution
La boucle n'est pas infinie.
Modifier le code
Modifier le code pour afficher le nombre de tours de boucles effectuées.
# Tests
(insensible à la casse)(Ctrl+I)
(Shift+Esc ; Ctrl pour inverser les colonnes)
(Esc)
Bilan
Nous allons étudier la représentation des réels dans la machine. Cela va nous permettre de comprendre ces comportements, et surtout d'apprendre qu'il y a des choses qu'il ne faut pas faire.
III. Codage en binaire des nombres à virgule⚓︎
1. Rappel sur la base 10⚓︎
5 | 3 | 2 | , | 3 | 6 | 1 |
---|---|---|---|---|---|---|
centaines | dizaines | unités | virgule | dixième | centième | millième |
\(532,361_{10} = 5 \times 10^2 + 3 \times 10^1 + 2 \times 10^0 + 3 \times 10^{-1} + 6 \times 10^{-2} + 1 \times 10^{-3}\)
2. En binaire⚓︎
\(101,11_{2} = (1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 + 1 \times 2^{-1} + 1 \times 2^{-2})_{10}=4 + 1 + \dfrac{1}{2}+ \dfrac{1}{4}=4+1+0.5+0,25=5.75_{10}\)
\(110,101_2=(1 \times 2^2 + 1 \times2^1 +0 \times 2^0 + 1 \times 2^{-1} +0 \times 2^{-2}+1 \times 2^{-3})_{10} =4+2+0,5+0,125=6,625_{10}\)
Ecriture dyadique
On dit que \(110,101_2\) est l'écriture dyadique de \(6,625_{10}\)
IV. conversion⚓︎
1. Méthode de conversion⚓︎
Exemple
Considérons le nombre \(3,6875\). Il se décompose en une partie entière (3) et une partie décimale (\(0,6875\)).
- partie entière : \(3=11_2\)
-
partie décimale : la conversion de \(0,6875\) se fait en plusieurs étapes.
👉 A chaque étape, on multiplie la partie décimale par 2 : -
\(0,6875 \times 2 = \textbf{1},375\) Partie décimale : \(0,375\)
- \(0,375 \times 2 = \textbf{0},75\) Partie décimale : \(0,75\)
- \(0,75 \times 2 = \textbf{1},5\) Partie décimale : \(0,5\)
- \(0,5 \times 2 = \textbf{1},0\) Partie décimale : \(0,0\)
- On pourrait continuer ... mais \(0,0 \times 2 = \textbf{0},0\) ...
👉 On s'arrête quand la partie décimale est nulle.
On prend ensuite le chiffre des unités de tous les nombres obtenus : 1011
Donc \(3,6875_{10}=11,1011_2\)
Exercice 1
Donner l'écriture binaire de 20,875.
- partie entière : \(20 = 10100_2\)
- partie décimale :
- \(0,875 \times 2 = \textbf{1},75\)
- \(0,75 \times 2 = \textbf{1},5\)
- \(0,5 \times 2 = \textbf{1}\)
Donc \(20,875=10100,111_2\)
Exercice 2
Donner l'écriture binaire de 0,2.
- partie entière : \(0 = 0_2\)
- partie décimale :
- \(0,2 \times 2 = \textbf{0},4\)
- \(0,4 \times 2 = \textbf{0},8\)
- \(0,8 \times 2 = \textbf{1},6\)
- \(0,6 \times 2 = \textbf{1},2\)
- \(0,2 \times 2 = \textbf{0},4\)
- et cela continue...
Le nombre 0,2 n'admet pas d'écriture binaire finie.
\(0,2_{10}=0,00110011..._{2}\)
Exercice 3
Donner l'écriture binaire de 0,1.
- partie entière : \(0 = 0_2\)
- partie décimale :
- \(0,1 \times 2 = \textbf{0},2\)
- \(0,2 \times 2 = \textbf{0},4\)
- \(0,4 \times 2 = \textbf{0},8\)
- \(0,8 \times 2 = \textbf{1},6\)
- \(0,6 \times 2 = \textbf{1},2\)
- \(0,2 \times 2 = \textbf{0},4\)
- et cela continue...
Le nombre 0,1 n'admet pas d'écriture binaire finie.
\(0,1_{10}=0,0001100110011..._{2}\)
Conclusion⚓︎
Mon info
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 comme ce que nous avons déjà vu dans la partie découverte :
remarque sur quelques flottants usuels
Parmi les nombres décimaux à un chiffre après la virgule (0.1, 0.2, 0.3 ...) seul 0.5 admet une écriture binaire finie ! Tous les autres ont une représentation en machine qui n'en donne qu'une valeur approchée.
V. Conséquences : la difficile manipulation des flottants⚓︎
Le type float
En python, les nombres non entiers sont du type float.
Remarque
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.
Une tragique histoire vraie
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)
VI. Comment faire des tests d'egalité sur les flottants ?⚓︎
Remarque
Première réponse : ON NE FAIT PAS DE TEST DE COMPARAISONS ENTRE FLOTTANTS.
Si a
et b
sont deux flottants, le test classique
a de grandes chances d'échouer :
Le script
🐍 Script Python | |
---|---|
renverra
On se débrouille autrement
Si vraiment un test d'égalité est nécessaire, on ne va pas tester l'égalité entre a
et b
mais leur proximité, grâce à la valeur absolue de leur différence.
La fonction abs(a-b)
renvoie un nombre positif égal à la distance entre a
et b
. Il faut alors décider d'un écart minimal e
en dessous duquel on considèrera que a
et b
sont égaux.
Le script
renverraVII. Codage des réels en machine⚓︎
1. La notation scientifique⚓︎
La notation scientifique
Les nombres très grands (ou très petits) ont une écriture décimale difficile à manipuler, à lire ou à utiliser on préfère les écrire en notation scientifique c'est à dire sous la forme :
\(a \times 10^n\)
où \(a\) appelé mantisse est un nombre compris entre 1 et 10 et \(n\) appelé exposant est un entier positif ou négatif.
Par exemple :
- \(760000000 = 7,6 \times 10^8\)
- \(0,00000000049 = 4,9 \times 10^{-10}\)
A retenir
Il faut un seul chiffre différent de zéro avant la virgule.
La notation scientifique en binaire
En binaire, le seul chiffre possible avant la virgule est donc 1 en notation scientifique.
Exemples
\(1010,0111_2=1,0100111_2 \times (2^3)_{10}\)
\(0,001101_2=1,101_2 \times (2^{-3})_{10}\)
2. La norme IEEE-754⚓︎
Source de l'image : By Codekaizen - Own work, CC BY-SA 4.0
La norme
\(s\) est le bit de signe (bit 63 représenté en bleu).
\(e\) est codé sur les 11 bits représentés en vert. C'est l'exposant décalé.
\(f\) est codé sur les 52 bits représentés en rouge.
La mantisse \(m\) est égale à \(1,f\). (Le "\(1,\)" étant évident n'est pas codé pour économiser un bit).
Soit \(x\) le réel ainsi codé :
\(x = (-1)^{s} \times m \times 2^{e-1023}\)
Exemple
\(0,01101_2=1,101_2 \times 2^{-2}_{10}\)
m = 1,101 est la mantisse
-
Signe positif donc \(s=0\)
-
m = 1,f
La mantisse en base 2 commence toujours par 1. Comme nous l'avons vu, On économise un bit en ne codant pas le 1 qui est devant la virgule.
On a donc f = 1010000000000...
- \(-2=e-1023\) donc \(e=1023-2=1021\)
Il faut donc écrire 1021 en binaire sur 11 bits. Par divisions successives, on trouve : \(1021_{10}=01111111101_2\)
👉 \(0,01101_2=2^{-2}+2^{-3}+2^{-5}=0.40625\)
Nous venons de voir comment ce nombre était codé dans notre machine :
\(0\) \(01111111101\) \(10100000000000000000000000000000000000000000000000000\)
VIII. Exercices⚓︎
1. \(1,3_{10}\)
- est représenté exactement en machine par \(\dfrac{3}{10}\)
- est représenté exactement en machine par \(0,11_2\)
- ne peut pas être représenté exactement en machine car c'est un nombre à virgule
- ne peut pas être représenté exactement car son écriture dyadique est illimitée
-
est représenté exactement en machine par \(\dfrac{3}{10}\) -
est représenté exactement en machine par \(0,11_2\) -
ne peut pas être représenté exactement en machine car c'est un nombre à virgule - ne peut pas être représenté exactement car son écriture dyadique est infinie
2. \(0,25_{10}\)
- est représenté exactement en machine par \(0,1_2\)
- est représenté exactement en machine par \(0,01_2\)
- ne peut pas être représenté exactement en machine car c'est un nombre à virgule
- ne peut pas être représenté exactement car son écriture dyadique est illimitée
-
est représenté exactement en machine par \(0,1_2\) - est représenté exactement en machine par \(0,01_2\)
-
ne peut pas être représenté exactement en machine car c'est un nombre à virgule -
ne peut pas être représenté exactement car son écriture dyadique est illimitée
3. Quelle est l'écriture décimale de \(0,11_2\) ?
- 0,5
- 0,25
- 0,75
- 0,3
-
0,5 -
0,25 - 0,75
-
0,3
4. Quelle est l'écriture dyadique de \(0,625_{10}\) ?
- \(0,101_2\)
- \(0,011_2\)
- \(0,110_2\)
- \(0,111_2\)
- \(0,101_2\)
-
\(0,011_2\) -
\(0,110_2\) -
\(0,111_2\)
5. Un seul des nombres suivants n'a pas une écriture finie en base 2, lequel ?
- \(1,25_{10}\)
- \(1,5_{10}\)
- \(1,6_{10}\)
- \(1,75_{10}\)
-
\(1,25_{10}\) -
\(1,5_{10}\) - \(1,6_{10}\)
-
\(1,75_{10}\)
6. coder 1/3 en binaire
Ecrire le codage de \(\dfrac{1}{3}\) en binaire.
Astuce 1
- \(\dfrac{1}{3} = 0,3333 ...\) avec des \(3\) répétés à l'infini.
- Vous pouvez utiliser la méthode apprise :
\(0,33333... \times 2 = \boxed{0},66666... (\dfrac{2}{3})\)
Astuce 2
\(0,66666... \times 2 = \boxed{1},33333...\) car \(\dfrac{2}{3} \times 2 = \dfrac{4}{3}=1+\dfrac{1}{3}\)
Solution
\(0,33333... \times 2 = \boxed{0},66666... =\dfrac{2}{3}\)
\(0,66666... \times 2 = \boxed{1},33333...\) car \(\dfrac{2}{3} \times 2 = \dfrac{4}{3}=1+\dfrac{1}{3}\)
\(0,33333... \times 2 = \boxed{0},66666...\)
\(0,66666... \times 2 = \boxed{1},33333...\)
Le processus se reproduit de façon identique.
Le codage de \(\dfrac{1}{3}\) en binaire est donc \(\boxed{0,010101010101...}\) la période 01 se répétant à l'infini.
7. Comment coder 1/3 dans une machine ?
Déduire du résultat de l'exercice précédent le codage de \(\dfrac{1}{3}\) avec la norme IEEE 754. Vous pourrez utiliser l'instruction bin
pour vous aider.
Solution
\(0,010101010101...=(1,0101010101...)_{2} \times (2^{-2})_{10}\)
\(-2=e-1023\) donc \(e=1023 - 2=1021\)
En utilisant des divisions successives, ou l'instruction bin(1021)
, on trouve que \(1021_{10}=1111111101_2\)
\(f = 01010101............\)
Le codage de \(\dfrac{1}{3}\) est donc :
\(0 \quad 01111111101 \quad 0101010101010101010101010101010101010101010101010101\)
IX. Compléments⚓︎
Après avoir téléchargé le fichier, vous pourrez le lire à partir de Basthon
🌐 TD à télécharger : Fichier reels_compl.ipynb
: "Clic droit", puis "Enregistrer la cible du lien sous"
Vous pouvez tester la représentation des réels en machine ici : IEEE754
X. Crédits⚓︎
- Une grande partie du II. de ce cours a été réalisée par Gilles LASSUS.
- Les QCM du VIII ont été réalisés par Fabrice Nativel.
# Tests
(insensible à la casse)(Ctrl+I)
(Shift+Esc ; Ctrl pour inverser les colonnes)
(Esc)