Nombres flottants 2

Nombres flottants 2 

 

On pourra se référer au cours Nombres flottants 1 pour revoir les notions d’écriture de nombres réels en base 2 avec une partie décimale, de mantisse et d’exposant normalisés ou non. 

 

Pour coder un nombre flottant, on fait ici l’hypothèse de travail d’un code sur 8 bits. 

Le premier bit, le bit de poids fort, est réservé au bit de signe. On attribue 4 bits pour la mantisse. On se rappellera qu’en écriture normalisée, la mantisse ne contient qu’un 1 à gauche de la virgule ce qui permet de l’omettre dans le codage et donc de gagner un bit avec cette convention. On écrit en résumé les décimales du nombre en écriture normalisée. 

Le nombre minimal que l’on peut écrire en ne considérant que la mantisse correspond à des 0 sur les 4 bits de la mantisse. Or, l’écriture étant normalisée, cela revient à écrire le nombre $overline{1,0000}^2$ c’est à dire 1.

Le nombre le plus grand correspond au nombre avec des 1 pour chacun des bits, soit $overline{1,1111}^2 = 1 + dfrac{1}{2} + dfrac{1}{4} + dfrac{1}{8} + dfrac{1}{16} = 1,9375$.

L’exposant est codé sur les bits restants : $8 – 1 – 4 = 3$. Or chaque bit peut prendre deux valeurs.

Ainsi 3 bits permettent de représenter $2^3 = 8$ entiers consécutifs, que l’on prendra pour l’exemple variant de $-3$ à $4$.

Le nombre flottant maximal que l’on peut coder correspond donc au produit de la mantisse maximale par l’exposant maximal : $x_{max} = overline{1,1111}^2 times 2^4 = left ( 1 + dfrac{1}{2} + dfrac{1}{4} + dfrac{1}{8} + dfrac{1}{16} right ) times 2^4 = 2^4 + 2^3 + 2^2 + 2^1 + 1 = 31$.

De même, le nombre flottant positif minimal que l’on peut coder correspond au produit de la mantisse minimal par l’exposant minimal, soit $x_{min} = overline{1,0000}^2 times 2^{-3} = 2^{-3} = 0,125$

L’écart minimal correspond à la soustraction du deuxième plus petit nombre flottant positif et du plus petit nombre flottant positif.
$epsilon = overline{1,0001}^2 times 2^{-3} – overline{1,0000}^2 times 2^{-3} = left (1 + dfrac{1}{16} right ) times 2^{-3} – 0,125 = 0,1328125 – 0,125 = 0,0078125. $

Cet écart correspond à différence minimale que doivent avoir deux nombres pour être considérés comme différents par l’ordinateur. 

Dans la pratique, en notamment avec Python, le codage des nombres flottants se fait avec le code IEEE 754, en double précision. La répartition des bits se fait comme suit : 1 bit de signe, 54 bits pour la mantisse et 11 bits pour l’exposant, ce qui permet de coder des exposants variant de -1023 à 1024.

Ainsi, le plus grand nombre que l’on peut coder vaut $x_{max} = 10^{308}$ et le plus petit positif $x_{min} = 10^{-308}$. De plus, l’écart minimal vaut $epsilon = 2^{-1077} approx 10^{-325}$. 

 

Codons par exemple le nombre flottant $x = -0,25$ sur 8 bits.

Il faut d’abord écrire le nombre en binaire. On peut alors remarquer que $x = -dfrac{1}{4} = -dfrac{1}{2^2} = -2^{-2} = -overline{0,01}^2$. En écriture normalisée, on a : $-overline{1,0000}^2 times 2^{-2}$. 
Il reste à présent à coder l’exposant -2 selon la méthode du complémentation à 2. Pour cela, on commence par coder la valeur absolue de -2 c’est à dire 2. Sur 3 bits, l’écriture binaire vaut $010$. Pour coder le signe, on utilise le complémentation à 2, à savoir inverser les 0 et les 1 puis ajouter 1 sur le bit de poids faible. Cela donne alors $110$.

Finalement, le code de $x$ est le suivant 1 110 0000. Le premier 1 correspond au bit de signe, les bits 110 correspondent à l’exposant, et 0000 correspondent à la mantisse (on se rappellera que l’on n’écrit pas le 1 à gauche de la virgule en écriture normalisée).

A présent, on suppose que $x = 0,1$. Cependant, on remarque que le développement en base 2 de ce nombre est illimité périodique, ou encore $x = overline{0,00011001100110011…}^2$.
On code désormais sur 16 bits, et on donne la répartition suivante : l’exposant sur 6 bits pour coder des entiers de -31 à 32 et la mantisse sur 9 bits. 
Pour pouvoir coder ce nombre, on commence par le transformer en écriture normalisée : $x = overline{1,1001100110011…}^2 times 2^{-4}$. Le codage de l’exposant se fait de la même manière que dans l’exemple précédent avec la méthode de complémentation à 2 et on trouve que $-4 = overline{111100}^2$. 

Il reste à présent à coder la mantisse. Cependant, comme le développement est illimité, il faut nécessairement effectuer un arrondi car on ne peut garder qu’un nombre fini de bits (9 ici). On conserve alors 9 chiffres après la virgule et $x$ vaut alors : $x approx overline{1,100110011}^2 times 2^{-4}$.
Le codage de ce nombre est alors 0 111100 100110011. On a donc du procédé à un arrondi du nombre pour pouvoir le coder. Cet exemple a donc permis de soulever une des limites du codage en flottant, que nous allons maintenant développer.

Le calcul avec les flottants est un calcul approché. Cela s’explique tout d’abord par l’écart minimal : si deux nombres ont un écart en deçà de cet écart, alors ils sont considérés comme égaux. Une autre explication de calcul approché est l’obligation d’avoir recours à des arrondis car les écritures décimales des nombres en base 2 peuvent être illimitées et potentiellement apériodiques si le nombre n’est pas rationnel. 

Si un nombre dépasse $x_{max}$ ou $x_{min}$, l’ordinateur ne peut plus les coder : c’est une erreur de dépassement de capacité, respectivement signalée par overflow et underflow

En informatique, deux nombres sont considérés comme égaux si leur différence est inférieure à l’écart minimal $epsilon$. Ainsi $x$ et $x + dfrac{1}{2} epsilon$ sont considérés comme égaux car leur différence vaut la moitié de l’écart minimal. Dans la mesure du possible, on évitera donc d’effectuer des tests d’égalité entre flottants.

Une autre limite est le phénomène d’absorption. 
On se propose d’aborder cette notion avec un exemple, en limitant la mantisse à 5 bits et en supposant qu’il n’y a pas de limite pour l’exposant pour simplifier.
On commence par calculer la somme $overline{1,10000}^2 + overline{0,000001}^2$ à la main. Le résultat est immédiat et donne $overline{1,10000}^2 + overline{0,000001}^2 = overline{1,100001}^2$.
On s’intéresse à présent à la manière dont l’ordinateur effectue ce calcul. 
Il faut tout d’abord écrire les termes en écriture normalisée : $overline{1,10000}^2 + overline{0,000001}^2 = overline{1,10000}^2 times 2^0 + overline{1,00000}^2 times 2^{-6}$. On somme ensuite les deux nombres et le résultat vaut alors $overline{1,10000}^2 times 2^0$ en ne conservant que 5 chiffres pour la mantisse. On remarque alors que le résultat est différent du calcul exact, car le dernier chiffre du résultat théorique n’a pas pu être représenté : on dit alors que $overline{0,000001}^2$ a été absorbé par $ overline{1,10000}^2$. 

Le phénomène de non associativité est une illustration du phénomène d’absorption.
Pour simplifier davantage, on suppose ici que la mantisse est codée sur 2 bits.
On souhaite calculer la somme $overline{1,00}^2 +overline{0,001}^2 +overline{0,001}^2 $. Le calcul direct à la main donne $overline{1,010}^2 $, en se rappelant que le calcul se fait en base 2. On a pu ici sommer le premier et le deuxième terme ensemble puis sommer le résultat avec le troisième ou bien sommer le deuxième et le troisième ensemble puis sommer le résultat avec le premier terme : c’est la propriété d’associativité de l’addition.
On s’intéresse à la manière dont va être effectué ce calcul par un ordinateur.
On effectue ce calcul de deux manières, en associant deux nombres différents à chaque fois.
$begin{aligned} overline{1,00}^2 + (overline{0,001}^2 +overline{0,001}^2)  &=& overline{1,00}^2 times 2^0 + (overline{1,00}^2 times 2^{-3} +overline{1,00}^2 times 2^{-3}) \ &=& overline{1,00}^2 times 2^0 + overline{1,00}^2 times 2^{-2} \ &=& overline{1,01}^2 times 2^0 end{aligned}$
Une autre manière d’effectuer ce calcul est $(overline{1,00}^2 + overline{0,001}^2) +overline{0,001}^2 = (overline{1,00}^2 times 2^0 + overline{1,00}^2 times 2^{-3}) +overline{1,00}^2 times 2^{-3}$. En ne conservant que deux bits pour la mantisse, on constate que le phénomène d’absorption se produit pour la première somme : $(overline{1,00}^2 times 2^0 + overline{0,001}^2) +overline{0,001}^2 = overline{1,00}^2 times 2^0 + overline{1,00}^2 times 2^{-3}$. Il en est de même pour la deuxième somme.
Finalement le résultat est $(overline{1,00}^2 + overline{0,001}^2) +overline{0,001}^2 = overline{1,00}^2times 2^0 = 1$ : il n’y a donc pas associativité dans le cadre de l’addition entre flottants. 

Nombre flottants 2 Compléments

Tu veux réviser 2x plus vite ?

Découvre les offres des Bons Profs avec :