CHAPITRE 6 : LA VIRGULE FLOTTANTE ET LA NORMALISATION

Un astronome écrit 1,5×1011 mètres, pas 150 000 000 000. Un chimiste écrit 6,02×1023. Ils séparent les chiffres qui comptent de l'ordre de grandeur. La virgule flottante transpose cette idée en binaire, et pose aussitôt un problème que la normalisation vient résoudre.

La forme générale

Un nombre réel est représenté sous la forme :

± m × be

  • un signe, + ou − ;
  • une mantisse m, qui porte les chiffres significatifs et s'écrit elle-même en virgule fixe ;
  • un exposant e, entier relatif, qui dit de combien de rangs il faut décaler la virgule ;
  • une base b, qui vaut 2 en machine (elle a valu 16 sur certains IBM des années 1960, et 10 dans les calculatrices financières).

Le nom vient de là : la virgule flotte, elle n'est plus clouée à une position fixe. Chaque nombre emporte avec lui l'indication de l'endroit où elle se trouve.

Quelques exemples dans différentes bases :

  • 0,5425×102 en base dix, c'est-à-dire 54,25 ;
  • 10,1×2−1 en base deux, c'est-à-dire 1,01 soit 1,25 ;
  • A0,B4×16−2 en base seize.

Le problème : une infinité d'écritures

Prenons 3,25, qui s'écrit 11,01 en virgule fixe binaire. On peut le mettre sous forme flottante de bien des manières :

11,01   x 2^0
1,101   x 2^1     on recule la virgule d'un rang
0,1101  x 2^2
110,1   x 2^-1    on avance la virgule d'un rang
11010   x 2^-2

Toutes ces écritures désignent le même nombre. C'est embêtant pour une machine, pour trois raisons :

  • deux nombres égaux pourraient avoir des motifs binaires différents, ce qui casse le test d'égalité ;
  • on gaspillerait des bits de mantisse en zéros de tête inutiles ;
  • comparer deux nombres deviendrait un calcul, alors qu'on voudrait que ce soit une simple comparaison de motifs.

La normalisation

La solution est une convention : on impose une seule écriture, celle où il y a exactement un chiffre non nul avant la virgule. En base deux, le seul chiffre non nul étant 1, cela donne :

± 1,M × 2e

Pour normaliser, on déplace la virgule jusqu'à ce qu'il n'y ait plus qu'un seul 1 devant, et on compense sur l'exposant :

  • si on recule la virgule de k rangs vers la gauche, on ajoute k à l'exposant ;
  • si on l'avance de k rangs vers la droite, on retranche k.
3,25  = 11,01      en virgule fixe
      = 1,101 x 2^1   ← forme normalisee

35,5  = 100011,1
      = 1,000111 x 2^5

0,625 = 0,101
      = 1,01 x 2^-1

Le dernier exemple montre que l'exposant peut être négatif : pour les nombres plus petits que 1, on doit avancer la virgule.

Le bit implicite : un bit gratuit

Voici l'astuce la plus élégante du format. Puisque tout nombre normalisé commence nécessairement par 1,, ce 1 n'apporte aucune information : il est toujours là. Alors on ne le stocke pas.

La mantisse rangée en mémoire ne contient que les chiffres après la virgule. Pour 1,000111 on stocke 000111 ; pour 1,101 on stocke 101.

On gagne un bit de précision sans dépenser un bit de place. C'est gratuit, et cela double la finesse du format.

Il faut en revanche se souvenir de le remettre à la lecture : une mantisse stockée 101 signifie la valeur 1,101 et non 0,101. C'est l'erreur de copie la plus répandue aux examens.

Et zéro ? Zéro ne peut pas se normaliser : il n'a aucun 1 à mettre devant la virgule. Comme le bit implicite vaut toujours 1, la forme normalisée ne peut jamais valoir 0. Il faut donc une convention particulière, réservée : nous la verrons au chapitre 7.

L'exposant biaisé

Dernière pièce. L'exposant est un entier relatif : il vaut 5 pour 35,5 et −1 pour 0,625. Il faudrait donc le coder en complément à 2, convention que nous connaissons bien.

Les concepteurs de la norme ont choisi autre chose : on ajoute à l'exposant une constante appelée biais, choisie assez grande pour que la somme soit toujours positive. On range alors un simple entier positif.

Eb = e + biais, avec biais = 2p−1 − 1 pour un exposant sur p bits

Sur 8 bits, le biais vaut 27 − 1 = 127. Ainsi l'exposant 5 se range comme 132, et l'exposant −1 comme 126.

Pourquoi se compliquer la vie ?

Pour une raison très concrète : comparer deux nombres flottants devient une comparaison d'entiers.

Avec un exposant biaisé, un exposant plus grand donne toujours un motif binaire plus grand. Comme l'exposant est placé juste après le bit de signe et avant la mantisse, deux nombres positifs se comparent en lisant leurs 32 bits comme un entier ordinaire : le matériel de comparaison des entiers suffit, on n'a rien de spécial à construire.

Avec un complément à 2, ce serait faux : l'exposant −1 s'écrirait 11111111 et l'exposant +1 s'écrirait 00000001. Le plus petit des deux porterait le plus grand motif, et la comparaison directe donnerait une réponse inversée.

C'est aussi pour cela que l'ordre des champs est signe, puis exposant, puis mantisse, et pas un autre : il place les informations par ordre d'importance décroissante, exactement comme les chiffres d'un nombre ordinaire.

Ce qu'il faut retenir

  • Forme générale : ± m × be, avec b = 2 en machine.
  • Normaliser, c'est imposer la forme ± 1,M × 2e : un seul 1 avant la virgule.
  • Reculer la virgule d'un rang augmente l'exposant de 1 ; l'avancer le diminue de 1.
  • Le 1 de tête n'est pas stocké : c'est le bit implicite, un bit de précision gratuit.
  • L'exposant est biaisé (Eb = e + 127 sur 8 bits) pour que la comparaison de deux flottants soit une comparaison d'entiers.
  • Zéro n'est pas normalisable : il lui faut une convention à part.

Exercices d'application

Exercice 1

Normalisez 118,625 en base deux et donnez son exposant.

Voir le corrigéMasquer le corrigé

Partie entière : 118 = 64+32+16+4+2 = 1110110.

Partie fractionnaire : 0,625 = 0,5 + 0,125 = 101.

Donc 118,625 = 1110110,101 en virgule fixe.

Il y a sept chiffres avant la virgule ; il faut la reculer de six rangs pour n'en laisser qu'un.

118,625 = 1,110110101 × 26

L'exposant vaut 6, et la mantisse stockée serait 110110101 suivie de zéros.

Exercice 2

Une mantisse stockée vaut 01000000000000000000000 et l'exposant réel vaut −3. Quel est le nombre, en base dix ?

Voir le corrigéMasquer le corrigé

On remet le bit implicite : la mantisse réelle est 1,01 (les zéros de queue ne comptent pas).

1,01 en base deux vaut 1 + 0,25 = 1,25.

1,25 × 2−3 = 1,25 / 8 = 0,15625

Si l'on avait oublié le bit implicite on aurait trouvé 0,25 × 2−3 = 0,03125, soit cinq fois moins. L'oubli ne se voit pas : le résultat reste plausible. C'est pourquoi il faut en faire un réflexe.

Exercice 3

Sur 5 bits d'exposant, quel est le biais ? Quel motif range-t-on pour un exposant réel de −4 ?

Voir le corrigéMasquer le corrigé

Biais = 25−1 − 1 = 16 − 1 = 15.

Eb = −4 + 15 = 11, qui s'écrit 01011 sur 5 bits.

Contrôle : en relisant, e = 11 − 15 = −4. C'est bien cela.

Exercice 4

Expliquez, en comparant deux motifs précis, pourquoi un exposant codé en complément à 2 casserait la comparaison directe de deux flottants.

Voir le corrigéMasquer le corrigé

Prenons deux nombres positifs, 21 et 2−1, de mantisse nulle, avec un exposant sur 8 bits.

En complément à 2 : l'exposant +1 donne 00000001, l'exposant −1 donne 11111111. Lus comme des entiers, les mots complets donneraient 2−1 > 21 : la comparaison est inversée.

En biaisé : +1 donne 128 = 10000000, −1 donne 126 = 01111110. L'ordre des motifs suit l'ordre des valeurs.

Le processeur peut donc comparer deux flottants positifs avec son comparateur d'entiers, sans décoder les champs. C'est tout l'intérêt.

Posez le calcul sur une feuille avant d'ouvrir le corrigé : le codage s'apprend au crayon, pas en lecture.

Questions / Réponses

Aucune question. Soyez le premier à poser une question.
★ ★ ★ ★ ★
2 votes. Moyenne 5 sur 5.

Ajouter un commentaire

Anti-spam