Vous êtes sur la page 1sur 7

Codage des nombres rels avec la norme IEEE-754 (i.e.

les flottants)

Ce document sadresse toute personne cherchant comprendre pourquoi et comment la norme IEEE-754 a t cre pour reprsenter les nombre rels, et en particulier aux tudiants dIUT dinformatique. Quelques bases mathmatiques sont requises (niveau Bac S) et une comprhension du codage binaire des entiers est un pralable indispensable. Je prends volontairement ici le contre-pied des livres techniques et de larticle wikipdia correspondant, pour essayer de faire comprendre progressivement et par lexemple, les tapes du raisonnement qui amnent au choix de cette norme. Vous pouvez cependant trouver une explication plus rigoureuse et scientifique sur le site du Wikipdia : http://fr.wikipedia.org/wiki/IEEE_754 Vous pouvez vous entrainer et vrifier vos rsultats sur le site http://www.binaryconvert.com

Pour toute question, remarque, faute corriger: http://perso.limsi.fr/pruvost

Gatan Pruvost

Introduction
La norme IEEE 754 permet de reprsenter des nombres virgule (i.e. des nombres rels). Ces nombres sont importants dans les ordinateurs puisquils permettent de faire du calcul scientifique, de la comptabilit, de la gestion Il est donc ncessaire de trouver un moyen de les reprsenter dans les ordinateurs. On reprsente gnralement ces nombres au moyen des symboles suivants : Chiffres 0 1 2 3 4 5 6 7 8 9 Virgule ,

Or, dans un ordinateur, on ne peut utiliser que 2 symboles : 0 1 . Le problme de lencodage (reprsenter une information sous forme de 0 et de 1) est considr comme rsolu pour les nombres entiers (cf codage binaire : http://fr.wikipedia.org/wiki/Code_binaire). Le codage binaire est suffisant pour nimporte quel nombre entier (positif ou ngatif), mais ne permet pas de reprsenter des nombres virgule. La norme IEEE-754 drive du binaire et propose une convention pour reprsenter la virgule. Pour cela, il faut d'abord comprendre comment on code en binaire un nombre virgule.

Nombres virgule en binaire


En dcimal : 0,1 est une autre notation pour 10-1 1,305 peut aussi scrire 1*100 + 3*10-1 + 0*10-2 + 5*10-3 De la mme faon, en binaire : 0,1 est une autre notation pour 2-1 11,101 peut aussi scrire 1*21 + 1*20 + 1*2-1 + 0*2-2 + 1*2-3 = 2 + 1 + 1/2 + 0 + 1/8 Si lon fait le calcul, (11,101) 2 vaut donc en dcimal (3,625) 10 Une fois que lon a compris cette notation, le problme est de passer de la notation binaire au dcimal et vice-versa. On vient de voir comment faire pour passer du binaire au dcimal sur lexemple 11,101. Pour passer du dcimal au binaire, cest un peu plus compliqu, il faut passer par la mthode des soustractions. Si je le fais sur lexemple 9,375. Le plus simple est de sparer le travail entre partie entire et aprs la virgule. Pour la partie entire (i.e. 9), la mthode des soustractions (cf cours) donne 1001. Notre nombre commence donc par 1001, Il reste coder 0,375. On travaille par la mthode des soustractions nouveau. Pour chaque chiffre aprs la virgule, on va se demander sil doit tre 0 ou 1 :

Gatan Pruvost

Premier chiffre aprs la virgule Si je mets ce chiffre 1, a veut dire que jajoute 2-1 qui vaut 0.5 en dcimal. Cest trop grand, donc le premier chiffre aprs la virgule est 0. Notre nombre commence par 0,0 Second chiffre aprs la virgule Si je le mets 1, jajoute 2-2 qui vaut 0.25 en dcimal. Cest pas mal, on se rapproche de notre nombre (0,375) 10 sans le dpasser. Je dis donc que mon nombre commence par 0,01 Cependant, on natteint pas encore (0,375) 10, il reste encore 0,375-0,25 = 0,125. Troisime chiffre aprs la virgule Si ce chiffre vaut 1, jajoute 2-3 mon nombre. Or 2-3 = 1/8 = 0.125. Cest exactement ce quil me manquait. Donc mon nombre vaut 0,011.

On sarrte l car on a fini par trouver notre nombre. Si le nombre est plus complexe, il faudra souvent rajouter beaucoup de chiffres aprs la virgule pour le reprsenter ( titre dexemple, essayez de coder 0,78125, vous devriez tomber sur 0,11001). Heureusement, en contrle, on se limitera des nombres plutt sympas. Pour conclure, on a trouv que (9) 10 = (1001) 2 et que (0,375) 10 = (0,011) 2. On en dduit que (9,375) 10 = (1001,011) 2. Ctait ltape la plus complique

La petite histoire de lIEEE754


Maintenant, on sait coder les nombres virgule en binaire. Mais si je vous donne le nombre (11010,001101) 2, vous ne pouvez toujours pas le faire rentrer dans votre ordinateur Que feriezvous de la virgule ?

Notation nave Pour pallier ce problme, on a invent une convention. En gros, lide nave consiste dire : Je mets juste les chiffres dans la mmoire. Dans notre exemple (11010,001101) 2 devient 11010001101. On appelle ces chiffres des chiffres significatifs ou mantisse (cest une dfinition un peu incorrecte de la mantisse, mais acceptable dans un premier temps) . Pour savoir o est la virgule, je vais dire de combien il faut se dcaler aprs le premier chiffre pour arriver la virgule. Ainsi, dans notre cas, il faut se dcaler de 5 chiffres pour avoir la virgule. On appelle ce nombre (5) lexposant. Je vais donc crire mon nombre dans la mmoire en 2 morceaux. Dabord jcris le nombre de lexposant, puis le nombre de la mantisse. Le codage naf serait donc 1011 11010001101.

Dans la pratique, cest lgrement plus compliqu. Pourquoi ? Si je considre le nombre (0,000 000 000 011) 2 . Cest un trs petit nombre Avec ma mthode nave , si je veux le faire rentrer sur Gatan Pruvost

8 bits, je ne peux pas car les 8 premiers bits seront des 0 et je nai pas assez de place pour faire rentrer les 1.

Optimisations Cette limite est purement lie notre convention puisque finalement, il ny a qu supprimer les zros inutiles et dire que la mantisse vaut 11 (les seuls chiffres significatifs). Dans ce cas, la virgule ne se trouve pas un certain nombre de chiffres aprs la mantisse mais plutt un certain nombre de chiffres avant la mantisse (ici 11 chiffres avant la mantisse). Il faut donc que mon exposant puisse tre positif (virgule aprs le dbut de la mantisse) ou ngatif (virgule avant le dbut de la mantisse) ! Dans la notation IEEE754, le champ de lexposant contient donc un nombre sign et la mantisse ne contient que les bits utiles (on supprime tous les zros avant car ils ne servent rien). De cette faon, on peut coder des nombres trs trs petits. Il ne faut pas oublier que cette norme sert aux calculs scientifiques et comptables dans les ordinateurs, il est donc important quelle soit prcise. On utilise donc la notation scientifique pour isoler les bits significatifs. Ainsi 0,000 000 000 011 devient 1,1*2-11. Avec la notation scientifique, le chiffre avant la virgule est toujours diffrent de 0 (sauf si le nombre vaut exactement 0). Donc, en binaire, mes nombres significatifs commenceront toujours par un 1. Encore une fois, si je mets toujours ce premier 1 dans ma mantisse, a ne sert rien, on perd un bit pour rien. Plutt que de gaspiller ce bit, on prfre le conserver pour des bits qui soient rellement utiles la prcision. On naffiche donc jamais le premier chiffre significatif dans la mantisse. Note facultative : On comprend mieux pourquoi cette partie est appele mantisse. En mathmatique, la mantisse est la partie situe aprs la virgule Avec cette notation, la mantisse est lensemble des chiffres significatifs situs aprs la virgule lorsque le nombre est en notation scientifique en binaire. Cest la dfinition (plus complexe) correcte de la mantisse en informatique. Ainsi, en IEEE754, on se ramnera toujours un nombre sous la forme binaire suivante: 1,1011 * 23 La partie rouge est la mantisse (notez quelle ne contient pas le 1 situ avant la virgule) et la partie verte est lexposant (positif ou ngatif). Pour crire un nombre, on juxtapose donc les bits de lexposant puis ceux de la mantisse. Oups. Comment reprsenter les nombre ngatifs de lexposant ? On pourrait utiliser lune des techniques que lon utilise avec les nombres binaires entiers : Avantage - Trs simple coder - Nombres positifs signs et non-signs ont la mme reprsentation Inconvnient - Comparaison bit a bit impossible - Addition avec ngatifs ncessite des tapes intermdiaires - 2 notations pour le nombre 0

Complment 1

Gatan Pruvost

Complment 2

Codage par excs

Calcul identique entre positifs et ngatifs (sans dcodage) Nombres positifs signs et non-signs ont la mme reprsentation Calcul identique entre positifs et ngatifs (sans dcodage) Comparaison identique entre positifs et ngatifs (sans dcodage)

Comparaison bit a bit impossible

Les nombres positifs ne signs et non-signs nont pas la mme reprsentation

Parmi ces trois techniques, celle qui est la plus intressante dans le cadre du codage de lexposant est celle du codage par excs. Pourquoi ? Parce que les 2 oprations les plus frquentes sur les exposants de deux nombres rels sont laddition et la comparaison (et comme nos exposants seront toujours signs, on se moque de ce quil y a dans la case inconvnient). On en conclut donc que si je veux coder 1,1011 * 23 = (13,5) 10 avec 5 bits dexposant et 10 bits de mantisse, jcrirais 00011 1011000000. Bon si vous avez bien suivi, vous remarquerez quil sagit dune erreur, lexposant est bien 101 mais il doit tre cod par excs. Sur 5 bits, je peux compter de 0 31 inclus, ou bien de -15 16 (je coupe la poire en deux). 00000 tant le plus petit nombre de mon codage par excs, il correspond -15. On en dduit que pour 5 bits, le codage par excs sobtient en additionnant 15 au nombre que lon veut obtenir (de la mme manire, sur 8 bits, il faudrait additionner 127).

Ainsi, mon nombre scrira 10010 1011000000. Et cette fois-ci, jai bien une notation complexe mais OPTIMALE (qui ne gche pas de bits et qui permet au processeur de faire les calculs le plus rapidement possible).

Ajout du signe Notre notation semble parfaite ceci prs que lon ne tient pas compte des nombres ngatifs. Si lon veut obtenir des nombres ngatifs, comment peut-on faire ? On ne peut pas utiliser les mthodes de complments (faites-moi confiance). On utilise donc une mthode plus simple, on rajoute un simple bit devant. Ainsi, le codage de (13,5) 10 devient Ainsi, le codage de (-13,5) 10 serait 0 10010 1011000000 1 10010 1011000000

Les diffrentes prcisions de lIEEE754 Nous lavons vu, la prcision des nombres que lon peut coder dpend du nombre de bits que lon met dans lexposant et dans la mantisse. La norme IEEE754 dfinit 3 formats de prcisions . Les deux plus courants sont :

Gatan Pruvost

Simple prcision (float en c++) : 8 bits pour lexposant (excs de 127) et 23 bits de mantisse Double prcision (double en c++) : 11 bits pour lexposant (excs de 1023) et 52 bits de mantisse

Mthode pour lencodage et le dcodage


Encodage en IEEE754 par lexemple Essayons dencoder le nombre +16,5 en simple prcision. 1) Encoder en binaire le nombre virgule (voir dbut du cours) +16,5 = (10000,1) 2 2) Transformer en notation scientifique (souvenez-vous que dcaler la virgule revient multiplier/diviser par 2) (10000,1) 2 = (1,00001*24) 2 3) Identifier les champs signe = 0 (positif) exposant = 4 mantisse = 00001 (on ne prend pas le 1,) 4) Encoder lexposant 4 doit tre cod sur 8 bits par excs de 127 => on encode 131 = (1000 0011) 2 5) Rsultat final (En contrle, crire tous les 0 la fin pour faire 32 bits) 0 10000011 00001000 Regroupage des bits par 4 0100 0001 1000 0100 0000 0000 En Hxa (ne pas oublier les 0 la fin pour faire 32 bits) 41 84 00 00 Dcodage du IEEE754 par lexemple Essayons de dcoder le nombre rel (4024000000000000) 16 qui est en double prcision (puisquil utilise 64 bits). 1) Analyser le nombre en binaire (on ne peut rien extraire de lhexa) 0100 0000 0010 0100 0000000 2) Identifier les champs signe : 0 (positif) exposant : 100 0000 0010 (11 bits en double prcision) mantisse : 010000 3) Dcoder lexposant On trouve un exposant affich de (100 0000 0010) 2 = (1026) 10 Gatan Pruvost

Mais il faut se rappeler que pour coder cet exposant, on lui avait ajout 1023 (sur 11 bits, codage par excs de 1023). Lexposant rel vaut donc 3. 4) Ecrire le nombre en binaire en notation scientifique (1,01*23) 2 5) En dduire le rsultat final : (1,01*23) 2 = (1010) 2 = (10) 10 (multiplier par 23 revient dcaler la virgule de 3 chiffres droite en binaire).

Gatan Pruvost