Retour à la page d'accueilNSI · Première (sans spé maths) · Changer de matière
Commencer gratuitement
Première (sans spé maths) · NSI
Types construits et algorithmique en première NSI · Représentation des données et architecture

Bases de numération, complément à 2, flottants et texte

Lina tape 0.1 + 0.2 dans Python et obtient 0.30000000000000004. Pourtant, la même machine affiche sans erreur sa photo de vacances en Corse. Comment un ordinateur, qui ne manipule que des 0 et des 1, représente-t-il des entiers, des nombres à virgule et du texte ? Et pourquoi ses calculs sont-ils parfois « faux » ? Réponse dans cette page.

Écrire un entier dans une base

Dans la vie courante, on écrit les nombres en base 10 : dix chiffres, et chaque chiffre vaut dix fois plus que celui de droite. Un ordinateur travaille avec deux états physiques (courant qui passe ou non) : il utilise la base 2, avec deux chiffres, 0 et 1, appelés bits.

En base 2, les « poids » des bits sont $1, 2, 4, 8, 16, 32, 64, 128\dots$ En base 16 (hexadécimal), on utilise seize symboles : $0$ à $9$ puis $\mathrm{A}=10$, $\mathrm{B}=11$, $\mathrm{C}=12$, $\mathrm{D}=13$, $\mathrm{E}=14$, $\mathrm{F}=15$.

Manipule les bits ci-dessous : chaque bit allumé ajoute son poids.

Pourquoi l'hexadécimal ? Parce que $16 = 2^4$ : un chiffre hexadécimal remplace exactement un groupe de 4 bits. C'est une écriture abrégée du binaire, bien plus lisible pour un humain. En Python, on écrit 0b10110101 pour le binaire et 0xB5 pour l'hexadécimal.

Décimal Binaire Hexa
0 0000 0
5 0101 5
9 1001 9
10 1010 A
12 1100 C
15 1111 F
Entraîne-toi★☆☆Pas commencé
a) Convertir $(1101\,0110)2$ en base 10. b) Convertir 183 en base 2. c) Convertir $(2F){16}$ en base 10 puis en base 2.
  1. a) Convertir $(1101\,0110)_2$ en base 10.
  1. b) Convertir 183 en base 2.
  1. c) Convertir $(2F)_{16}$ en base 10 puis en base 2.
Résoudre

Combien de bits faut-il ?

Un octet (symbole o) regroupe 8 bits. Avec $n$ bits, on peut former $2^n$ combinaisons différentes. Si on les utilise pour écrire des entiers positifs (non signés), on représente tous les entiers de $0$ à $2^n - 1$.

Pourquoi ? Avec $n-1$ bits on atteint au plus $2^{n-1} - 1$ ; si $N$ est plus grand, il faut un bit de plus. Les tailles usuelles de registres et de variables sont 8, 16, 32 et 64 bits.

Les quantités de données se mesurent en octets, avec les préfixes du système international (puissances de 1 000) : $1\ \text{ko} = 1\,000\ \text{o}$, $1\ \text{Mo} = 10^6\ \text{o}$, $1\ \text{Go} = 10^9\ \text{o}$, $1\ \text{To} = 10^{12}\ \text{o}$. Les préfixes kio, Mio, Gio désignent des puissances de 1 024 ($1\ \text{kio} = 1\,024\ \text{o}$) ; on les rencontre moins souvent.

Entraîne-toi★☆☆Pas commencé
a) Combien de bits faut-il au minimum pour écrire l'entier 300 en binaire ? b) Combien de valeurs différentes peut-on représenter avec 10 bits ? c) Quel est le plus…
  1. a) Combien de bits faut-il au minimum pour écrire l'entier 300 en binaire ?
  1. b) Combien de valeurs différentes peut-on représenter avec 10 bits ?
  1. c) Quel est le plus grand entier non signé représentable sur 12 bits ?
Résoudre
Entraîne-toi★★★Pas commencé
On code une image en niveaux de gris de 1 920 × 1 080 pixels, chaque pixel étant codé sur 8 bits. a) Calculer la taille de l'image non compressée en octets, puis en Mo…

On code une image en niveaux de gris de 1 920 × 1 080 pixels, chaque pixel étant codé sur 8 bits.

  1. a) Calculer la taille de l'image non compressée en octets, puis en Mo (1 Mo = $10^6$ octets).
  1. b) On passe à une image couleur avec 3 octets par pixel. Calculer la nouvelle taille et le nombre de couleurs possibles.
  1. c) Une vidéo de 25 images par seconde de cette image couleur dure 90 minutes. Calculer le volume brut en To et expliquer pourquoi la compression est indispensable.
Résoudre

Les entiers relatifs : le complément à 2

Comment représenter $-5$ avec seulement des 0 et des 1 ? On pourrait réserver un bit pour le signe, mais l'addition deviendrait compliquée. La solution retenue par les machines est le complément à 2.

Sur $n$ bits, on partage les $2^n$ codes en deux moitiés : ceux qui commencent par 0 représentent les entiers positifs, ceux qui commencent par 1 les entiers négatifs.

Les 256 codes sur 8 bits : la première moitié représente les entiers de 0 à 127, la seconde les entiers de −128 à −1. entiers positifs entiers négatifs 0000 0000 0111 1111 1000 0000 1111 1111 0 127 −128 −1

Pourquoi ça marche ? Sur $n$ bits, les calculs se font « modulo $2^n$ » : on perd la retenue qui sort à gauche. Le code de $-x$ est celui de $2^n - x$, car $x + (2^n - x) = 2^n$ s'écrit $1\,0\dots0$ et la retenue finale disparaît, ce qui donne $0$. Or $2^n - x = (2^n - 1 - x) + 1$, et $2^n - 1 - x$ est précisément $x$ dont on a inversé les bits (le nombre $2^n - 1$ est formé uniquement de 1). Du coup, l'addition ordinaire fonctionne sans traitement particulier pour les entiers positifs comme négatifs.

Entraîne-toi★☆☆Pas commencé
a) Donner la représentation en complément à 2 sur 8 bits de $+25$ et de $-25$. b) Quelle est la plage des entiers représentables en complément à 2 sur 8 bits ? c) Quel…
  1. a) Donner la représentation en complément à 2 sur 8 bits de $+25$ et de $-25$.
  1. b) Quelle est la plage des entiers représentables en complément à 2 sur 8 bits ?
  1. c) Quel entier est représenté par $(1111\,1100)_2$ en complément à 2 sur 8 bits ?
Résoudre
Entraîne-toi★★☆Pas commencé
a) Effectuer l'addition binaire $(0110\,1101)2 + (0010\,1011)2$ et vérifier en base 10. b) Calculer en complément à 2 sur 8 bits $17 - 42$ en additionnant 17 et la…
  1. a) Effectuer l'addition binaire $(0110\,1101)_2 + (0010\,1011)_2$ et vérifier en base 10.
  1. b) Calculer en complément à 2 sur 8 bits $17 - 42$ en additionnant 17 et la représentation de $-42$. Donner le résultat en binaire et en décimal.
  1. c) Dans quel cas y a-t-il dépassement de capacité en complément à 2 ?
Résoudre
Entraîne-toi★★★Pas commencé
a) Montrer que pour représenter tous les entiers de 0 à $N$ il faut $\lfloor \log_2 N \rfloor + 1$ bits (on suppose $N \geq 1$). b) Montrer que l'opposé d'un entier $x$…
  1. a) Montrer que pour représenter tous les entiers de 0 à $N$ il faut $\lfloor \log_2 N \rfloor + 1$ bits (on suppose $N \geq 1$).
  1. b) Montrer que l'opposé d'un entier $x$ tel que $0 < x < 2^{n-1}$ en complément à 2 sur $n$ bits s'obtient comme $2^n - x$, et que cela revient à inverser les bits puis ajouter 1.
  1. c) En déduire que l'addition de deux entiers en complément à 2 sur $n$ bits est correcte tant que le résultat reste dans $[-2^{n-1}, 2^{n-1}-1]$.
Résoudre

Les nombres à virgule : les flottants

Comme pour les entiers, on peut écrire un nombre décimal en binaire. Après la virgule, les poids sont $\frac12, \frac14, \frac18, \dots$ c'est-à-dire $2^{-1}, 2^{-2}, 2^{-3}, \dots$

Pour convertir la partie après la virgule, on la multiplie par 2 de façon répétée : la partie entière obtenue à chaque étape est le bit suivant.

Certains nombres décimaux « simples » ont un développement binaire infini. C'est le cas de $0{,}1$ et de $0{,}2$. Or la mémoire est finie : la machine ne garde qu'un nombre limité de bits, donc une valeur approchée.

Un nombre flottant s'écrit sous la forme $(-1)^s \times 1{,}m \times 2^{e - \text{biais}}$, avec un bit de signe $s$, un exposant $e$ et une mantisse $m$ (les chiffres après la virgule). En double précision (le float de Python), il y a 64 bits : 1 de signe, 11 d'exposant et 52 de mantisse. Aucune norme précise n'est à connaître, mais le principe l'est.

Dans un format simplifié avec 3 bits d'exposant (biais 3) et 4 bits de mantisse, le nombre $(1\ 011\ 1000)_2$ se décode ainsi : $s = 1$ (négatif), $e = (011)_2 = 3$ donc $2^{3-3} = 1$, mantisse $1{,}1000_2 = 1{,}5$. Valeur : $-1{,}5$.

Entre $2^E$ et $2^{E+1}$, les flottants sont répartis régulièrement, mais chaque fois que l'exposant augmente de 1, l'écart entre deux flottants voisins double. Les flottants sont donc très serrés près de 0 et de plus en plus espacés quand on s'éloigne.

Sur une droite graduée de 1 à 8, les flottants sont serrés entre 1 et 2, deux fois moins serrés entre 2 et 4, et encore deux fois moins entre 4 et 8. 1 2 4 8 16 valeurs 16 valeurs 16 valeurs
>>> 0.1 + 0.2

0.30000000000000004

>>> 0.1 + 0.2 == 0.3

False

>>> abs((0.1 + 0.2) - 0.3) < 1e-9

True

L'égalité est fausse parce que $0{,}1$, $0{,}2$ et $0{,}3$ sont stockés sous forme approchée, et les petites erreurs ne se compensent pas exactement. En revanche, $0{,}25 = (0{,}01)_2$ est stocké exactement.

Retour au début : le résultat de Lina vient donc de l'approximation de $0{,}1$ et de $0{,}2$, pas d'un bug de Python.

Entraîne-toi★★☆Pas commencé
a) Convertir le nombre décimal $0,625$ en binaire. b) Écrire $0,1$ en binaire sur les 8 premiers chiffres après la virgule et expliquer pourquoi 0.1 + 0.2 == 0.3 vaut…
  1. a) Convertir le nombre décimal $0,625$ en binaire.
  1. b) Écrire $0,1$ en binaire sur les 8 premiers chiffres après la virgule et expliquer pourquoi 0.1 + 0.2 == 0.3 vaut False en Python.
  1. c) Écrire les trois champs (signe, exposant, mantisse) d'un flottant en double précision et donner leur nombre de bits.
Résoudre
Entraîne-toi★★★Pas commencé
On étudie un format simplifié de flottant sur 8 bits : 1 bit de signe, 3 bits d'exposant (biais 3) et 4 bits de mantisse, avec la valeur…

On étudie un format simplifié de flottant sur 8 bits : 1 bit de signe, 3 bits d'exposant (biais 3) et 4 bits de mantisse, avec la valeur $(-1)^s \times 1,m \times 2^{e-3}$.

  1. a) Décoder $(0\,101\,0110)_2$.
  1. b) Quel est le plus petit réel strictement positif représentable (avec exposant non nul) ?
  1. c) Montrer que l'écart entre deux flottants consécutifs double quand l'exposant augmente de 1, et en déduire pourquoi les flottants ne sont pas régulièrement répartis.
Résoudre

Représenter du texte

Un caractère est un nombre : on associe à chaque lettre, chiffre ou symbole un code. Il faut que l'émetteur et le récepteur utilisent le même encodage, sinon on obtient des « é » mal affichés dans un message.

Encodage Taille d'un caractère Caractères Intérêt
ASCII 7 bits (stocké sur 1 octet) 128 : lettres sans accent, chiffres, ponctuation, codes de contrôle Simple, base de tout le reste
ISO 8859-1 (latin-1) 8 bits = 1 octet 256 : ASCII + lettres accentuées d'Europe occidentale (é, à, ç…) Convient au français, mais pas aux autres alphabets
Unicode (via UTF-8) de 1 à 4 octets plus d'un million de points de code : tous les alphabets, symboles, émojis Universel ; compatible avec l'ASCII

En ASCII, 'B' a pour code $66 = (42)_{16}$. Les lettres se suivent : 'C' = 67, 'D' = 68… Une minuscule a un code qui dépasse de 32 celui de la majuscule correspondante. En Python : ord('B') renvoie 66 et chr(67) renvoie 'C'.

UTF-8 est un encodage à longueur variable : les 128 caractères ASCII restent sur 1 octet (un fichier ASCII est donc aussi un fichier UTF-8 valide), les lettres accentuées prennent 2 octets, des symboles comme € en prennent 3 et un émoji 4.

Entraîne-toi★★☆Pas commencé
a) Donner le code ASCII (en décimal puis en hexadécimal) de A (65) et de a. Quelle relation lie majuscule et minuscule ? b) Expliquer la différence entre ASCII, ISO…
  1. a) Donner le code ASCII (en décimal puis en hexadécimal) de A (65) et de a. Quelle relation lie majuscule et minuscule ?
  1. b) Expliquer la différence entre ASCII, ISO 8859-1 et UTF-8 et dire combien d'octets occupe é en UTF-8.
  1. c) Un fichier texte de 2 000 caractères ASCII est enregistré en UTF-8. Quelle est sa taille en octets ? Et si tous les caractères sont des é ?
Résoudre

L'essentiel

  • Base $b$ : un entier se décompose en puissances de $b$. En binaire, les poids sont $1, 2, 4, 8\dots$ ; un chiffre hexadécimal = 4 bits.

  • Avec $n$ bits : $2^n$ valeurs, donc les entiers de $0$ à $2^n - 1$. Il faut $\lfloor \log_2 N \rfloor + 1$ bits pour écrire $N$ ; la somme de deux entiers de $n$ bits tient sur $n+1$ bits et leur produit sur $2n$ bits.

  • Unités : $1\ \text{o} = 8$ bits ; ko, Mo, Go, To sont des puissances de 1 000.

  • Complément à 2 sur $n$ bits : plage $[-2^{n-1} ; 2^{n-1} - 1]$ ; $-x$ s'obtient en inversant les bits de $x$ puis en ajoutant 1 ; l'addition se fait comme pour les entiers positifs, en oubliant la retenue finale. Attention au dépassement de capacité.

  • Flottants : représentation approchée (signe, exposant, mantisse ; 1 + 11 + 52 bits en double précision). On ne teste jamais l'égalité de deux flottants avec ==.

  • Texte : ASCII (7 bits), ISO 8859-1 (1 octet par caractère), UTF-8 (1 à 4 octets, compatible ASCII).

Retour au début : 0.1 + 0.2 != 0.3 parce que $0{,}1$ et $0{,}2$ n'ont pas d'écriture binaire finie.

Voir tous les exercices de cette partie