- Accueil
- TUTORIELS
- ARCHITECTURE DES ORDINATEURS
- CODAGE DES NOMBRES
- La norme IEEE 754
CHAPITRE 7 : LA NORME IEEE 754
Avant 1985, chaque constructeur avait son propre format
flottant. Un même programme donnait des résultats différents selon la machine,
et porter du code scientifique relevait de l'artisanat. La norme IEEE 754 a
mis fin à ce désordre. Elle est aujourd'hui gravée dans tous les processeurs,
et c'est elle que décrivent les types float et
double.
Le découpage du mot
La norme reprend tout ce que nous avons construit au chapitre 6 : un bit de signe, un exposant biaisé, une mantisse normalisée à bit implicite. Elle fixe simplement la taille de chaque champ.
| Champ | Simple précision | Double précision |
|---|---|---|
| Signe (S) | 1 bit | 1 bit |
| Exposant biaisé (Eb) | 8 bits | 11 bits |
| Mantisse (M) | 23 bits | 52 bits |
| Total | 32 bits | 64 bits |
| Biais | 127 | 1023 |
| Type en C, Java | float |
double |
La formule de lecture est toujours la même :
valeur = (−1)S × 1,M × 2(Eb − biais)
Coder un nombre, en quatre étapes
La méthode ne change jamais. Prenons 35,5 en simple précision.
Etape 1 : le signe
35,5 est positif -> S = 0
Etape 2 : virgule fixe, puis normalisation
35,5 = 100011,1 (32 + 2 + 1 = 35, et 0,1 = 0,5)
= 1,000111 x 2^5 (la virgule recule de 5 rangs)
l'exposant reel est e = 5
Etape 3 : l'exposant biaise
Eb = e + 127 = 5 + 127 = 132
132 = 10000100 sur 8 bits
Etape 4 : la mantisse sur 23 bits
on retire le 1 implicite : il reste 000111
on complete par des zeros a droite :
M = 00011100000000000000000
Resultat :
0 10000100 00011100000000000000000
S Eb M
soit 42 0E 00 00 en hexadecimal
Deux vérifications qui sauvent des points. Comptez les bits de la mantisse : il doit y en avoir exactement 23, pas 22 ni 24. Et complétez toujours par des zéros à droite : compléter à gauche décalerait tous les chiffres et changerait le nombre.
Décoder un mot
On fait le chemin inverse. Soit le mot :
0 10000001 11100000000000000000000
- S = 0, donc le nombre est positif.
- Eb =
10000001= 129, donc e = 129 − 127 = 2. - M =
111suivi de zéros. En remettant le bit implicite : 1,111.
1,111 × 22 = 111,1 en base deux = 4 + 2 + 1 + 0,5 = 7,5
Un second, négatif cette fois :
1 10000010 01101000000000000000000
S = 1, donc négatif. Eb = 130, donc e = 3. Mantisse réelle :
1,01101. On décale la virgule de trois rangs vers la
droite : 1011,01 = 8 + 2 + 1 + 0,25 = 11,25. Le nombre est
−11,25.
Les motifs réservés
La norme met de côté deux valeurs d'exposant, celles dont tous les bits sont à 0 ou tous à 1. Elles ne servent pas à des nombres normalisés mais à des cas particuliers.
| Eb | Mantisse | Signification |
|---|---|---|
| 0 | nulle | zéro (+0 si S = 0, −0 si S = 1) |
| 0 | non nulle | nombre dénormalisé : très petit, sans bit implicite |
| 1 à 254 | quelconque | nombre normalisé : le cas ordinaire |
| 255 | nulle | l'infini (+∞ ou −∞) |
| 255 | non nulle | NaN, Not a Number |
C'est pour cela que l'exposant réel en simple précision ne va que de −126 à +127, et non de −127 à +128 : les deux extrêmes sont confisqués.
- Zéro existe en deux exemplaires, +0 et −0, puisque
le bit de signe est indépendant. La norme impose toutefois que la comparaison
+0 == -0soit vraie. - Les dénormalisés comblent le trou entre zéro et le plus
petit normalisé. Leur mantisse se lit
0,Mau lieu de1,M, et leur exposant est figé à −126. On y perd en précision, mais la perte est graduelle au lieu d'être brutale. - L'infini est le résultat d'un débordement ou d'une division par zéro. Il se propage dans les calculs : ∞ + 3 = ∞.
- NaN est le résultat d'une opération qui n'a pas de
sens : 0/0, √−1, ∞ − ∞. Sa
particularité est d'être le seul nombre différent de lui-même :
x != xest le test classique pour le détecter.
Les caractéristiques chiffrées
| Simple précision | Double précision | |
|---|---|---|
| Bits de signe | 1 | 1 |
| Bits d'exposant | 8 | 11 |
| Bits de mantisse | 23 | 52 |
| Nombre total de bits | 32 | 64 |
| Biais de l'exposant | 127 | 1023 |
| Exposant réel | −126 à +127 | −1022 à +1023 |
| Plus petit normalisé | 2−126 ≈ 1,18×10−38 | 2−1022 ≈ 2,23×10−308 |
| Plus grand fini | ≈ 3,40×1038 | ≈ 1,80×10308 |
| Chiffres décimaux sûrs | environ 7 | environ 15 |
La dernière ligne est celle qu'il faut retenir pour programmer. Vingt-quatre
bits de mantisse (23 stockés plus l'implicite) représentent
24×log10(2) ≈ 7,2 chiffres décimaux. Au-delà du
septième chiffre significatif, un float ne garantit plus rien.
Un montant en francs CFA au-delà de 10 millions ne tient plus
au franc près dans un float. Pour de l'argent, on n'utilise ni
float ni double : on compte en unités entières
indivisibles.
Ce qu'il faut retenir
- Simple précision : 1 + 8 + 23 bits, biais 127. Double : 1 + 11 + 52 bits, biais 1023.
- valeur = (−1)S × 1,M × 2Eb−biais.
- Coder : signe, virgule fixe, normalisation, Eb = e + 127, mantisse complétée à 23 bits par des zéros à droite.
- Décoder : e = Eb − 127, remettre le bit implicite, déplacer la virgule de e rangs.
- Eb = 0 et Eb = 255 sont réservés : zéro, dénormalisés, infinis, NaN.
- Précision utile : 7 chiffres décimaux en simple, 15 en double.
Exercices d'application
Codez 12,75 en IEEE 754 simple précision et donnez le résultat en hexadécimal.
Voir le corrigéMasquer le corrigé
Signe : positif, S = 0.
Virgule fixe : 12 = 1100 et 0,75 = 11, donc 12,75 = 1100,11.
Normalisation : 1,10011 × 23, donc e = 3.
Exposant biaisé : Eb = 3 + 127 = 130 = 10000010.
Mantisse : 10011 complété à 23 bits, soit 10011000000000000000000.
0 10000010 10011000000000000000000
Regroupé par quatre : 0100 0001 0100 1100 0000 0000 0000 0000, soit 41 4C 00 00.
Décodez 1 10000001 10010000000000000000000.
Voir le corrigéMasquer le corrigé
S = 1 : le nombre est négatif.
Eb = 10000001 = 129, donc e = 129 − 127 = 2.
Mantisse réelle : 1,1001.
On décale la virgule de deux rangs à droite : 110,01 = 4 + 2 + 0,25 = 6,25.
Le nombre est −6,25.
Codez 2 026 en simple précision. Combien de bits de mantisse sont réellement utilisés ?
Voir le corrigéMasquer le corrigé
2 026 = 1024 + 512 + 256 + 128 + 64 + 32 + 8 + 2, soit 11111101010 : onze bits.
Normalisation : 1,1111101010 × 210, donc e = 10 et Eb = 137 = 10001001.
Mantisse : 1111101010 complété à 23 bits.
0 10001001 11111010100000000000000
Dix bits de mantisse sont utilisés, les treize autres sont à zéro. Le nombre est donc représenté exactement : tout entier jusqu'à 224 l'est.
Un programme affiche inf après avoir multiplié deux nombres. Quel motif binaire contient la variable, et qu'aurait affiché le même calcul en double précision ?
Voir le corrigéMasquer le corrigé
Le motif est l'infini positif : exposant à 255 et mantisse nulle, soit 0 11111111 00000000000000000000000.
Cela signifie que le produit a dépassé 3,4×1038, la plus grande valeur finie en simple précision.
En double précision, la limite est 1,8×10308 : environ 270 ordres de grandeur plus haut. Le même calcul donnerait très probablement un résultat fini.
C'est l'une des raisons pour lesquelles les bibliothèques de calcul scientifique travaillent en double par défaut, même quand la précision du float suffirait.
Posez le calcul sur une feuille avant d'ouvrir le corrigé : le codage s'apprend au crayon, pas en lecture.
Questions / Réponses
Ajouter un commentaire