Skip to content

Représentation des entiers relatifs et des flottants

Nous avons vu précédemment comment écrire les nombres entiers naturels en binaire :

  • (101)2=1×22+0×21+1×20=4+0+1=5
  • (1111)2=1×23+1×22+1×21+1×20=8+4+2+1=15

Nous avons vu aussi que les nombres entiers étaient codés au niveau machine sur un nombre d'octets bien défini :

  • sur 1 octet, on code 28=256 nombres, soit les nombres de 0 à 255 ;
  • sur 2 octets, on code 216=65 536 nombres, soit les nombres de 0 à 65 535 (en C, c'est le type int) ;
  • sur 4 octets, on code 2324,3×109 nombres (en C, c'est le type long) ;
  • sur 8 octets, on code 2641,8×1019 nombres (en C, c'est le type long long).

Enfin nous avons constaté que les opérations arithmétiques basiques ( addition, soustraction, multiplication,...) étaient compatibles avec cette notation.

Il nous faut maintenant nous intéresser aux autres possibilités de nombres : les nombres signés (relatifs) et les nombres flottants(décimaux).

Les Entiers Relatifs (entiers signés)

Une version naïve

Proposition : le bit de signe

Sur un octet, le bit de poids fort - c'est-à-dire le bit le plus à gauche du nombre - représente le signe (0 pour positif et 1 pour négatif) et les 7 autres représentent la valeur absolue du nombre.

Exercice

  1. Quelle est la représentation de 3 dans ce système ?
  2. Quelle est la représentation de 4 dans ce système ?
  3. Quel est le plus grand nombre représentable sur un octet ?
  4. Quel est le plus petit nombre représentable sur un octet ?
  5. Combien de nombres sont alors représentés ?
  6. Quel problème pouvez-vous déjà constater ?
  7. Effectuer l'addition binaire des nombres 3 et 4. Le résultat est-il logique ?

A venir !

Les problèmes de la méthode naïve

On constate donc que cette méthode naïve n'est pas du tout efficace pour représenter des entiers relatifs :

  • premièrement il existe deux représentations pour zéro : +0 et 0, mais ce n'est pas un réel problème mathématiquement. Tout au plus une perte de place en utilisant deux représentations différentes pour le même objet.
  • deuxièmement, et c'est beaucoup plus embêtant, l'incompatibilité de cette représentation avec les opérations usuelles.

Il faut donc trouver une méthode qui permettra d'être compatible avec les opérations.

Représentation en complément à 2

Représentation en complément à 2

Pour remédier aux problèmes soulevés par la version naïve, on utilisera la représentation en complément à deux. Dans cette notation, sur un octet :

  • Les nombres positifs sont représentés comme pour les nombres entiers naturels.
  • Pour les nombres négatifs, par contre :
    • On détermine l'écriture binaire de la valeur absolue du nombre, généralement sur un octet.
    • On inverse les bits de l'écriture binaire , ce qu'on appelle le complément à 1 (cela correspond à une opération logique NON sur chaque bit, donc 1 devient 0 et 0 devient 1) ;
    • On ajoute 1 au résultat, les dépassements (overflow, voir plus bas) étant ignorés - ce qui signifie qu'on reste bien sur le nombre de bits définis dans l'étape 1.

Exemple

  • Le nombre 13 est représenté par (0000 1101)2.
  • Pour le nombre 4 :
    • on cherche d'abord la représentation de sa valeur absolue : (0000 0100)2 ;
    • ensuite on inverse chaque bit : (1111 1011)2
    • puis on ajoute 1 au résultat : (1111 1100)2

Le nombre 4 a pour représentation en complément à 2 sur un octet la suite (1111 1100)2

Pour les curieux : « Overflow »

Ce qu'on appelle un « OVERFLOW » consiste en un dépassement de capacité lors d'une opération. Par exemple pour des nombres entiers écrits en binaire sur 1 octet, il est parfois possible qu'une opération dépasse les possibilités de stockage sur 1 octet.

Prenons pour exemple l'opération 130+132 :

  • en décimal, pas de soucis, 130+132=262 ;
    • 130=128+2=27+21=(1000 0010)2
    • 132=128+4=27+22=(1000 0100)2
    • Lorsqu'on effectue la somme en binaire sur 1 octet, le résultat reste sur 1 octet, d'où :

    en binaire sur 1 octet :

    10000010+1000010000000110

    Le résultat donné par une machine effectuant des additions sur 1 octet est donc 130+132=5... Il y a eu « integer overflow », donc dépassement des capacités de la machine à traiter les nombres entiers.

Obtenir un « overflow » est une preuve de mauvaise prise en compte des capacités limites de la machine. C'est un bug redouté et redoutable, en particulier lorsqu'on utilise des structures de « Piles » (au programme de terminale) lors d'opération « récursives » (aussi au programme de terminale). On obtient alors une erreur qui est appelée « Stack Overflow ». Cette erreur est tellement fréquente et tellement célèbre qu'elle a donné son nom au plus grand forum dédié à la programmation, Stack Overflow.

Pour votre culture numérique, le plus célèbre des « integer overflow » a été un bug qui a couté 500 millions de dollars lors du premier lancement de la fusée Ariane 5.

Exercice

  1. Compléter le tableau suivant (un calcul par élève) :
Nombre relatifV.A binaire sur 1 octetComplément à 1Complément à 2Entier Naturel128506412832127451881
  1. Quel est le bit de poids fort sur chacun des nombres donnés ?
  2. Quel relation existe-t-il entre les nombres relatifs et leur entier naturel correspondant ?
  3. Quel est le plus grand nombre représentable sur un octet ?
  4. Quel est le plus petit nombre représentable sur un octet ?
  5. Combien de nombre sont alors représentés ?
  6. Effectuer l'addition binaire de 45 et 13. Est-elle compatible avec l'opération décimale ?

A venir !

Complément à 2

Le nombre entier relatif x négatif possède le même codage sur n bits que le nombre entier naturel 2n|x|.

Remarque

Un algorithme simple pour trouver un complément à 2 de tête est de garder tous les chiffres de la valeur absolue depuis le bit de poids faible jusqu'au premier 1, puis d'inverser tous les suivants. Par exemple :

  • Pour obtenir le code de 40 sur 1 octet :
    • Le nombre 40 s'écrit (0010 1000)2
    • On garde la partie à droite (0010 1000)2
    • On inverse la partie à gauche après le premier 1 (1101 1000)2
    • On a ainsi obtenu le codage du nombre 40 sur 1 octet.
  • Pour obtenir le code de 65 sur 1 octet :
    • Le nombre 65 s'écrit (0100 0001)2
    • On garde uniquement le bit de poids faible (0100 0001)2
    • On inverse tous les autres bits (1011 1111)2
    • On a ainsi obtenu le codage du nombre 65 sur 1 octet.

Les Flottants

Représentation de la partie décimale d'un nombre en écriture binaire

Représentation de la partie décimale en base 10

En base 10, on a :

23,145=2×101+3×100+1101+4102+510323,145=2×101+3×100+1×101+4×102+5×103

Partie « décimale » en écriture binaire

De la même manière qu'en écriture de base 10, on aura :

(10,0101)2=1×21+0×20+0×21+1×22+0×23+1×24=2+0+02+14+08+116=2+0+0+0,25+0+0,0625=2,3125

Convertir de la base 10 à la base 2

On cherche à convertir en binaire le nombre 13,6875. On commence par convertir la partie entière 13=(1101)2. Il faut ensuite convertir la partie décimale 0,6875. Pour y arriver on applique l'algorithme suivant :

  • on multiplie 0,6875 par 2 : 0,6875×2=1,375, et on note le résultat 1+0,375 ;
  • on multiplie 0,375 par 2 : 0,375×2=0,75, et on note le résultat 0+0,75 ;
  • on multiplie 0,75 par 2 : 0,75×2=1,5, et on note le résultat 1+0,5 ;
  • on multiplie 0,5 par 2 : 0,5×2=1, et on note le résultat 1, la partie décimale étant nulle on arrête l'algorithme ;

On récupère les parties entières obtenues à chaque étape, soit 1011, qui représente la partie décimale de notre nombre. D'où :

13,6875=(1101,1011)2

Exercice

  1. Trouver la représentation décimale de (100,0011)2.
  2. Trouver la représentation binaire de (6,625)10.
  3. Trouver la représentation binaire de (0,1)10. Que remarque-t-on ?

A venir !

Remarque

Tout comme le nombre 13 ne possède pas d'écriture décimale finie, certains nombres ne possèdent pas d'écritures binaires finies.

Écriture scientifique des nombres en écriture binaires

Écriture décimale scientifique

Pour écrire de très grands nombres, ou de très petits, on utilise souvent une écriture scientifique, c'est-à-dire sous la forme a×10n, où a[1;10[ et nZ. Ainsi :

  • 4 571,23=4,57123×103
  • 0,003 45=3,45×103

Écriture scientifique en binaire

Pour écrire un nombre binaire en « écriture scientifique », on l'écrira sous la forme a×2n, où :

  • a est un nombre binaire, avec partie « après la virgule » et dont la partie entière est 1 ;
  • n est un nombre entier relatif, écrit en binaire.

Exemple

  • Pour écrire le nombre 11010 en « écriture scientifique », il faudra décaler la virgule de 4 rangs sur la gauche, soit une puissance positive. Or 4=(100)2. Donc 11010=1,1010×2100.
  • Pour écrire le nombre 0,001011 en « écriture scientifique », il faudra décaler la virgule de 3 rangs sur la droite, soit une puissance négative, or 3=(11)2. Donc 0,001011=1,011×211.

Représentation des flottants en machine

Le contenu de cette partie est largement issu de Pixees.fr.

Norme IEEE 754

La norme IEEE 754 est la norme la plus employée pour la représentation des nombres à virgule flottante dans le domaine informatique. La première version de cette norme date de 1985.

Nous allons étudier deux formats associés à cette norme : le format dit « simple précision » et le format dit « double précision ». Le format « simple précision » utilise 32 bits pour écrire un nombre flottant alors que le format « double » utilise 64 bits. Dans la suite nous travaillerons principalement sur le format 32 bits.

Que cela soit en simple précision ou en double précision, la norme IEEE 754 utilise :

  • 1 bit de signe (1 si le nombre est négatif et 0 si le nombre est positif);
  • des bits consacrés à l'exposant (8 bits pour la simple précision et 11 bits pour la double précision);
  • des bits consacrés à la mantisse (23 bits pour la simple précision et 52 bits pour la double précision).

Flottant_machine.png

Nous pouvons vérifier que l'on a bien 1+8+23=32 bits pour la simple précision et 1+11+52=64 bits pour la double précision.

Déterminer la mantisse

Pour écrire un nombre au format IEEE 754, il est nécessaire de commencer par écrire notre nombre sous « écriture scientifique » binaire, sous la forme 1,XXXXX.2e.

Ainsi on sait déjà que le nombre 11010=1,1010×2100.

La partie « XXXXX » du nombre, c'est-à-dire 1010, correspond à la mantisse. Mais comme la mantisse doit contenir exactement 23 bits en simple précision, il faut donc la compléter avec 234=19 zéros à droite pour obtenir 23 bits, soit :

10100000000000000000000

Exposant des nombres flottants

Notre première intuition serait de dire que la partie exposant correspond simplement au « e » de 1,XXXXX.2e (dans notre exemple 1,1010×2100, nous aurions 100). En fait, c'est un peu plus compliqué... En effet, comment représenter les exposants négatifs, sachant que dans la norme IEEE 754, aucun bit pour le signe de l'exposant n'a été prévu. Il a donc été nécessaire de choisir une méthode, et c'est celle du décalage d'exposant qui a été retenue :

  • en simple précision, on décale l'exposant de 127 ;
  • en double précision, on décale l'exposant de 1 023.

Déterminer l'exposant

Pour le format simple précision, 8 bits sont consacrés à l'exposant, il est donc possible de représenter 256 valeurs, nous allons pouvoir représenter des exposants compris entre (126)10 et (+127)10 (les valeurs 127 et +128 sont des valeurs réservées, nous n'aborderons pas ce sujet ici, mais vous trouverez des précisions sur l'article IEEE 754 de wikipedia}). Pour avoir des valeurs uniquement positives, il va falloir procéder à un décalage : ajouter systématiquement 127 à la valeur de l'exposant.

Dans notre exemple, on a 11010=1,1010×2100. L'exposant est donc 4=(100)2, et pour le représenter il faut donc le décaler : 4+127=131 soit 131=(10000011)2. L'exposant possède 8 chiffres binaires, il n'est donc pas nécessaire de rajouter de zéros à gauche.\

Au format simple précision, le nombre 11010 s'écrit donc :

01000001110100000000000000000000

Exemple

Soit le nombre « 10,125 » en base 10. Représentons-le au format simple précision :

  • nous avons (10)10=(1010)2 et (0,125)10=(0,001)2 soit (10,125)10=(1010,001)2 ;
  • décalons la virgule : 1010,001 = 1,010001.23, soit avec le décalage de l'exposant 1,010001.2130, en écrivant l'exposant en base 2, nous obtenons 1,010001.210000010 ;
  • nous avons donc : notre bit de signe = 1 (nombre négatif), nos 8 bits d'exposant = 10000010 et nos 23 bits de mantisse = 01000100000000000000000
  • soit en "collant" tous les "morceaux" :
11000001001000100000000000000000

Exercice

  1. Déterminez la représentation au format simple précision de (0,25)10 en binaire.
  2. Déterminez la représentation au format simple précision de (0,1)10 en binaire.
  3. Soit le nombre flottant au format simple précision : 00111101110011001100110011001100. Trouvez la représentation en base 10 de ce nombre.
  4. À l'aide de Thonny, tapez dans la console : 0.1+0.2. Faites de même dans la console Javascript de Firefox. Que constate-t-on ? Pourquoi ?

A venir !