Arithmétique des nombres réels

Comment traiter les nombres réels ?

le problème principal est de savoir comment convertir un nombre à virgule en binaire. La première idée que l’on aurait serait de convertir chaque partie d’un nombre en binaire.

Faisons le test : prenons 7,5, et convertissons le en binaire : 111,101. Nous connaissons déjà une méthode de vérification, qui est la décomposition algébrique. La décomposition se fait avec les exposants décroissants. Dès que l’exposant est négatif, le nombre obtenu est inférieur à 1. Notre nombre décomposé sera donc :

 2^2+2^1+2^0+2^{-1}+2^{-3} = 4+2+1+1/2+1/8 = 7,625 !

La méthode employée est donc incorrecte. De plus, imaginez convertir 7,625…La partie décimale risque d’être longue !

Une bonne méthode peut se trouver en analysant justement la décomposition algébrique.

Nombres à virgule fixe

La méthode qui nous vient naturellement à l’esprit est cette des nombres dits « à virgule fixe ». Prenons par exemple le
nombre binaire 1101,0110. Nous pourrions le traduire en base 10 comme ceci :

 2^3+2^2+2^0+2^{-2}+2^{-3} = 8+4+1+1/4+1/8 = 13,375

Pour convertir un nombre décimal en binaire, nous devons traiter séparément la partie entière et la partie fractionnaire. Pour convertir la partie entière, nous savons déjà qu’il faut diviser successivement par 2 (pour avoir les différentes puissances). La partie fractionnaire s’obtient par des multiplications successives par 2. Si le résultat dépasse 1, il est reporté dans la seconde colonne.

Par exemple, le nombre 78,4610 :

/278,46×2
7800,46
391092
191184
91168
40136
20072
11144


088


176

La conversion en binaire d’une partie fractionnaire ne sera jamais précise ! Il y a toujours une erreur due à la troncature. Le nombre 78,4610 = 100 1110,0111 012 avec une précision absolue de 2-6. En d’autres termes, nous savons que le résultat n’est pas exact, mais nous assumons une erreur à partir du 7e bit de la partie fractionnaire (soit une erreur de maximum 0,007812510).

Le problème de la virgule fixe, c’est qu’elle demande énormément d’espace mémoire !

Prenons l’exemple suivant : nous souhaitons afficher tous les nombres réels entre 0 et 256. Les entiers dans cet intervalle prennent 8 bits. Si on veut une précision absolue de 2-8, la partie fractionnaire sera également sur 8 bits. Nous allouons donc 16 bits (2 octets) pour chaque nombre.

Pour les nombres entiers et les nombres ayant peu de décimales, il y a un gaspillage de bits à droite. Pour de petits nombres, il y a aussi un gaspillage de bits à gauche. Par exemple :
810= 0000 0100,0000 00002.

Actuellement, nous disposons de quantités énormes de mémoire, ce qui ne poserait pas de problèmes, mais au début de l’informatique, avoir 8 Mo de RAM était presque un luxe !

Nombres à virgule flottante

« Nous allons faire flotter les virgules ». La notation à virgule flottante, ou notation scientifique est une approximation d’un nombre réel. Un nombre au format scientifique se définit par une mantisse et un exposant. L’écriture scientifique d’un nombre s’obtient en plaçant le premier chiffre significatif à gauche de la virgule, les autres chiffres à droite, suivis d’une « correction » avec un facteur de 10.

Exemple : 0,005012510.Le premier chiffre significatif est le 5. Or, le 5 est au rang 10-3. La notation scientifique sera donc : 5,0125 .10-3, ou 5,0125e-3.

Exemple : 1307,56510. Le premier chiffre significatif est le 1, et au rang 103. La notation scientifique est 1,307565e3.

La mantisse comporte une partie entière et une partie fractionnaire.

Pourquoi appeler ça la « virgule flottante » ? Si on regarde un nombre à virgule fixe, la virgule reste « fixée » aux unités. Dans la notation scientifique, la virgule va « flotter » jusqu’au premier chiffre significatif, en faisant varier e.

Le principe reste le même pour n’importe quelle base.

Exemple : 0011 1100, 0111 10102 = 1,1110 0011 1101 0.25

Il reste cependant un problème. L’affichage en virgule flottante nécessite un chiffre significatif. Or, en binaire, seul le « 1 » est un chiffre significatif. Dans ce cas, comment représenter un nombre réel négatif ?

Le standard IEEE

L’IEEE (Institute of Electrical and Electronics Engineers) propose quatre formats de notation des nombres à virgules flottantes :

  • Le format demi précison, sur 16 bits (peu employé) ;
  • Le format simple précision, sur 32 bits ;
  • Le format simple précision étendu, sur 43 bits. Pratiquement, il est obsolète et remplacé par le standard double précision ;
  • Le format double précision sur 64 bits ;
  • Le format double précision étendu sur 80 bits.

Dans la norme IEEE, un nombre flottant est formé de trois éléments :

  • Le bit de signe (1 pour négatif) ;
  • L’exposant décalé (et non l’exposant !), de 5 à 15 bits ;
  • La mantisse du nombre, de 10 à 64 bits.
Dans la version 80 bits, la mantisse retient la partie entière. Dans les versions 32 et 64 bits, la mantisse ne conserve que la partie fractionnaire.

L’interprétation d’un nombre binaire se définit par la formule

 latex s \cdot 2^{e-d}-1,m   : où: 
  • s est le signe ;
  • e-d est l’exposant décalé (e = exposant et d = décalage) ;
  • m est la mantisse (uniquement la partie fractionnaire).

Exposant décalé

L’exposant permet de déterminer de combien de rangs il faut déplacer la virgule, ainsi que le sens de déplacement. Or, l’utilisation du complément à 2 n’est pas utilisée pour coder l’exposant, car elle rendrait les nombres flottants difficiles à comparer. Les ordinateurs utilisent la convention de l’exposant décalé (ou exposant biaisé). L’exposant décalé sera toujours un nombre positif, auquel il faut extraire le décalage. Le décalage est une valeur constante, mais dépendante du nombre de bits attribué à l’exposant.

   d=2^{n-1}-1  

Où :

  • d est le déplacement ;
  • n est le nombre de bits attribué à l’exposant.

Pour les nombres IEEE 32 bits, d= 28-1-1, soit 127.

L’exposant réel équivaut donc à e-d, soit un nombre situé entre -126 et + 127. Cette méthode permet de conserver un exposant décalé toujours positif, mais il permet en plus de gérer des cas indéterminés.

Conversion d’un nombre décimal en nombre à virgule flottante

Méthode
  1. Convertir le nombre décimal en binaire à virgule fixe, avec une précision suffisante ( pour un float, comptez 23 bits de précision à partir du premier bit à 1);
  2. Décaler la virgule en affichage scientifique;
  3. Écrire la mantisse au standard IEEE (uniquement la partie fractionnaire);
  4. Calculer l’exposant biaisé;
  5. Écrire le nombre en binaire en tenant compte du signe (1 pour négatif), suivi de l’exposant biaisé converti en binaire (sur 8 bits pour un float), puis la partie fractionnaire de la mantisse.

Exemple 1 : écrire 1215,010 en float.

  1. Conversion en binaire « fixe » : 100 1101 1111,0 ;
  2. Écriture en virgule flottante : 1,0011 0111 112 .210 ; ;
  3. Écriture de la mantisse au standard IEEE 32 (23 bits sans la partie entière) : 001 1011 1110 0000 0000 00002 ;
  4. Calcul de l’exposant biaisé : e+d = 1010 + 12710 = 13710 ;
  5. Conversion en binaire de l’exposant (sur 8 bits): 1000 10012 ;
  6. Écriture du nombre au standard IEEE : 0100 0100 1001 1011 1110 0000 0000 00002 ou 0x449B E000
Dans la notation IEEE, l’opposé de 1215 (-1215) s’écrit en passant le MSB à 1.

Exemple 2 : écrire -782, 15310 en float.

  1. Conversion en binaire fixe : 11 0000 1110,0001 0011 001010… ;
  2. Écriture en virgule flottante : 1,1000 0111 0000 1001 1001 0102.29 ;
  3. Écriture de la mantisse au standard IEEE : 100 0011 1000 0100 1100 10102 ;
  4. Calcul de l’exposant biaisé e+d = 910+12710 = 13610 ;
  5. Conversion de l’exposant en binaire : 1000 10002 ;
  6. Écriture du nombre au standard IEEE : 1100 0100 0100 0011 1000 0100 1100 10102 ou 0xC443 84CA.

Exemple 3 : écrire 0,0001710 en float.

  1. En binaire fixe : 0,0000 0000 0000 0101 1001 1010 0111 0010 1011 1000…
  2. Virgule flottante : 1,0110 0110 1001 1100 1010 1110 .2-14
  3. Mantisse : 011 0011 0100 1110 0101 0111
  4. Exposant : -1410+12710 = 11310 = 0100 10112
  5. standard IEEE : 0010 0101 1011 0011 0100 1110 0101 0111 ou 0x25D3 4E57

Conversion d’un nombre en virgule flottante en nombre décimal

Méthode
  1. Séparer le signe, l’exposant et la mantisse;
  2. Ajouter le 1, de la partie entière à la mantisse;
  3. Calculer l’exposant réel en soustrayant le biais;
  4. Dénormaliser le nombre (= le convertir en nombre à virgule fixe);
  5. Convertir le nombre en décimal;
  6. Convertir le bit de signe en signe;

Exemple : 0XE7, nombre de 8 bits avec 3 bits d’exposants :

  1. Convertissons 0XE7 en binaire : 1110011.
  2. Séparons nos données : 1110 0011.
  3. L’exposant biaisé est donc 110 = 6. L’exposant réel est 6 – (23-1-1) = 3
  4. La mantisse est 1,0011.
  5. le nombre binaire dénormalisé est donc de « – » 1,0011.23, donc 1001,1
  6. La conversion en décimal est donc 8+ 2+1+0,5 = 11,5

Utilisez l’exerciseur pour vous entraîner !

Cas particuliers

Le MSB de la mantisse est déterminé par l’exposant. Or, que se passe-t-il si :

  • l’exposant vaut 0 ?
    • Si la mantisse vaut 0, on obtient une des deux représentations du 0 (dépendant du signe).
    • Si la mantisse est non nulle, on obtient un nombre dit dénormalisé. Il est conseillé de ne pas avoir de nombre dénormalisé, car ils sont source d’erreurs.
  • L’exposant biaisé vaut 2e-1 (tous les bits de l’exposant sont à 1) ?
    • Si la mantisse est nulle, on obtient la représentation de ±, selon le signe.
    • Si la mantisse est non nulle, on obtient la représentation du NaN (not a number), utilisé pour la gestion d’erreur (0/0…)

en résumé :

Cas particuliers (type float)
Exposant biaisé Mantisse Signification
0 0 ±0
0 ≠0 Nombre dénormalisé
255 0 ±∞
255 ≠0 NaN

Le cas des nombres dénormalisés ne sera pas vu au cours.

Arithmétique des nombres réels

L’arithmétique avec des nombres réels suit les mêmes règles qu’en base décimale. Néanmoins, elle est beaucoup plus compliquée à réaliser que sur des nombres entiers.

Addition et soustraction

Pour additionner ou soustraire deux nombres réels :

  1. On vérifie qu’un des deux nombres est égal à 0. Dans ce cas, la réponse est immédiate ;
  2. On aligne les mantisses. On fait réapparaître le bit de la partie entière, puis on décale la mantisse du plus petit nombre (l’exposant le plus bas) vers la droite en incrémentant l’exposant.
  3. On additionne / soustrait les mantisses.
  4. On normalise le résultat.

Attention ! Comme la mantisse est un nombre fini, il peut y avoir des erreurs d’arrondi !

Multiplication et division

Pour multiplier ou diviser deux nombres réels :

  1. On vérifie qu’un des deux nombres est égal à 0. Dans ce cas, la réponse est soit 0, soit une erreur.
  2. On additionne (multiplication) ou on soustrait (division) les exposants. Dans ce cas, il n’y a pas de décalage à effectuer. Attention ! Il faut rectifier le biais ! Soit il a été compté 2x (multiplication), soit il a été soustrait (division).
  3. Si le résultat dépasse la taille de l’exposant, on signale une erreur et l’opération s’arrête.
  4. On multiplie ou on divise les mantisses, puis on arrondit la mantisse à sa taille (23 bits pour IEEE 32).

Erreurs d’arrondis1

Voici quelques exemples catastrophiques dus à des erreurs d’arrondis.

Le 25 février 1991, une batterie américaine de missiles Patriot, a échoué dans l’interception d’un missile Scud irakien. Le Scud a frappé un baraquement de l’armée américaine et a tué 28 soldats. La commission d’enquête a conclu à un calcul incorrect du temps de parcours, dû à un problème d’arrondi. Les nombres étaient représentés en virgule fixe sur 24 bits. Le temps était compté par l’horloge interne du système en 1/10 de seconde. Malheureusement, 1/10 n’a pas d’écriture finie dans le système binaire : 1/10 = 0,110 = 0,0001100110011001100110011…2. L’ordinateur de bord arrondissait 1/10 à 24 chiffres, d’où une petite erreur dans le décompte du temps pour chaque 1/10 de seconde. Au moment de l’attaque, la batterie de missile Patriot était allumée depuis environ 100 heures, ce qui avait entraîné une accumulation des erreurs d’arrondi de 0,34 s.. Pendant ce temps, un missile Scud parcourt environ 500 m, ce qui explique que le Patriot soit passé à côté de sa cible.

Le 4 juin 1996, une fusée Ariane 5 a explosé 40 secondes après l’allumage. La fusée et son chargement avaient coûté 500 millions de dollars. La commission d’enquête a rendu son rapport au bout de deux semaines. Il s’agissait d’une erreur de programmation dans le système inertiel de référence. À un moment donné, un nombre codé en virgule flottante sur 64 bits (qui représentait la vitesse horizontale de la fusée par rapport à la plate-forme de tir) était converti en un entier sur 16 bits. Malheureusement, le nombre en question était plus grand que 32768 ( > au max sur 16 bits), et la conversion a été incorrecte.

1Source : http://www.apprendre-en-ligne.net/bloginfo/index.php/2008/10/10/79-problemes-d-arrondi

Print Friendly, PDF & Email