Aller au contenu

Les flottants

En base b, un flottant est un nombre de la forme $$ s \times m \times b^e$$

  • s est le signe (+ ou -) ;
  • m est la mantisse. C'est un nombre à p chiffres, avec exactement un chiffre (non nul) avant la virgule ;
  • e est l'exposant, avec e_{min} \leq e \leq e_{max}.

Attention

Les nombres p, e_{min} et e_{max} sont des nombres écrits en base b et donnés dès le départ.
Ils permettent de définir une norme (une convention) de représentation des flottants en base b.

Note

La définition donnée ci-dessus n'est pas tout à fait la définition générique des flottants, mais nous nous tiendrons à cette approche pour simplifier.
Il s'agit donc de nombres pour lesquels nous imposons l'écriture en notation scientifique.
Les nombres de chiffres pour m et pour e sont bornés : cela permet de tenir compte des contraintes des nombres en machine qui seront toujours représentés avec le même nombre, nécessairement fini, de bits (sur les machines actuelles, usuellement 64 bits).

Un exemple en base 10

  1. Faire la liste des flottants en imposant p = 2, e_{min} = -1 et e_{max} = 1.

    Réponse
    1. Les mantisses possibles sont :

      • 1,0 ; 1,1 ; 1,2 ; ... ; 1,9
      • 2,0 ; 2,1 ; 2,2 ; ... , 2,9
      • ...
      • 9,0 ; 9,1 ; 9,2 ; ... ; 9,9
    2. Les exposants possibles sont -1, 0 et 1.

    3. Les flottants tels que p = 2, e_{min} = -1 et e_{max} = 1 sont donc :

      • Les nombres :

        • 0,10 ; 0,11 ; 0,12 ; ... ; 0,19 (c'est-à-dire 1,0 × 10-1 ; 1,1 × 10-1 ; 1,2 × 10-1 ; ... ; 1,9 × 10-1)

        • 0,20 ; 0,21 ; 0,22 ; ... , 0,29 (c'est-à-dire 2,0 × 10-1 ; 2,1 × 10-1 ; 2,2 × 10-1 ; ... ; 2,9 × 10-1)

        • ...

        • 0,90 ; 0,91 ; 0,92 ; ...; 0,99 (c'est-à-dire 9,0 × 10-1 ; 9,1 × 10-1 ; 9,2 × 10-1; ... ; 9,9 × 10-1)

      • Les nombres :

        • 1,0 ; 1,1 ; 1,2 ; ... ; 1,9 (c'est-à-dire 1,0 × 100 ; 1,1 × 100 ; 1,2 × 100 ; ... ; 1,9 × 100)

        • 2,0 ; 2,1 ; 2,2 ; ... ; 2,9 (c'est-à-dire 2,0 × 100 ; 2,1 × 100 ; 2,2 × 100 ; ... ; 2,9 × 100)

        • ...

        • 9,0 ; 9,1 ; 9,2 ; ... ; 9,9 (c'est-à-dire 9,0 × 100 ; 9,1 × 100 ; 9,2 × 100 ; ... ; 9,9 × 100)

      • Les nombres :

        • 10 ; 11 ; 12 ; ... ; 19 (c'est-à-dire 1,0 × 101 ; 1,1 × 101 ; 1,2 × 101 ; ...; 1,9 × 101)

        • 20 ; 21 ; 22 ; ... ; 29 (c'est-à-dire 2,0 × 101 ; 2,1 × 101 ; 2,2 × 101 ; ... ; 2,9 × 101)

        • ...

        • 90 ; 91 ; 92 ; ... ; 99 (c'est-à-dire 9,0 × 101 ; 9,1 × 101 ; 9,2 × 101 ; ... ; 9,9 × 101)

      • Et les opposés de ces nombres.

  2. Que pout-on dire de l'écart entre un nombre et le nombre suivant avec cette représentation ?

    nombre suivant

    On peut déjà remarquer que la notion de « nombre suivant » a un sens alors qu'elle n'en a pas avec les nombres réels.

    Une solution

    Raisonnons uniquement sur les positifs.

    Entre deux « petits » nombres consécutifs (par exemple entre 0,10 et 0,11), l'écart est 0,01.

    Entre deux « grands » nombres (par exemple 90 et 91), l'écart est 1.

Conséquences de cet exemple

Avec la représentation précédente, tous les réels de l'intervalle [0,10; 0,105[ (ouvert ou fermé à droite, choix possible) seront représentés par le même flottant : 1,0 \times 10^{-1}.

Et tous les réels de l'intervalle [10; 10,5[ seront représentés par le flottant 1,0 \times 10^1.

Ainsi, suivant qu'il s'agit de nombres proches de 0 ou éloignés de 0, chaque réel aura pour représentant dans les flottants un nombre plus ou moins éloigné de lui. Ou en d'autres termes, un même flottant représentera chacun des réels d'un intervalle plus ou moins grand.

Remarque

La remarque porte sur l'écart absolu (valeur absolue de la différence entre le nombre et son représentant flottant).
Les écarts relatifs (valeur absolue du quotient (écart absolu)/nombre) sont par contre « un peu plus constants » pour les ensembles de flottants usuellement utilisés en machine (et c'est là une propriété importante pour le calcul scientifique en machine).

La conséquence la plus importante est qu'on ne peut pas attendre que les opérations sur les flottants aient les mêmes propriétés que les opérations sur les réels.

Exemple

Nous avons déjà constaté cela. Par exemple la non commutativité avec:

>>> 1 + 10**(-16) -1
0.0
>>> 1 - 1 + 10**(-16)
1e-16
Pouvez-vous expliquer la différence de résultat dans les deux lignes précédentes?

Une explication

On a:

>>> 1+10**(-16)
1.0

tandis que

>>> 0 + 10**(-16)
1e-16

Sans rentrer dans les détails, on peut reprendre ce qui est exposé plus haut :

  • 10**(-16) est proche de 0 et aura un représentant flottant assez fidèle,
  • 1 + 10**(-16) est plus éloigné de 0 et les réels entre 1 et 1 + 10**(-16) auront tous 1 pour représentants.

Dans 1 + 10**(-16) -1, on évalue 1 + 10**(-16) qui donne 1 puis on évalue 1 - 1, on obtient 0.

Dans 1 - 1 + 10**(-16), on évalue 1 - 1 qui donne 0 puis on évalue 0 + 10**(-16), on obtient 10**(-16).

Flottants binaires et norme IEEE 754

Les flottants binaire sont représentés en général en machine suivant la norme IEEE 754. Ce nombre est de la forme :

(-1)^s \times m \times 2^{n-d}

Dans le format binary64, les flottants sont codés sur 64 bits selon le schéma ci-dessous :

1 11 52
signe (s) exposant (e) mantisse (m)
  • Le premier bit (à gauche) représente le signe s : 0 pour un positif, 1 pour un négatif ;
  • Les 11 bits suivants représentent l'exposant e.
    Pour connaître la valeur de l'exposant représenté, on traduit la suite de bits par un entier positif (écrit en binaire) puis on enlève le décalage d de valeur 1023 (on enlève 127 dans un codage 32 bits).
  • Les 52 bits restants correspondent aux bits se trouvant après la virgule du flottant.
    C'est la mantisse m privée du 1 qui se trouve avant la virgule (car il y a forcément un 1 devant la virgule en binaire).

Exemple

Quel nombre décimal est représenté par le mot de 64 bits suivant :

1 \; 10000000110 \;1010110110000000000000000000000000000000000000000000
Une solution
  • Le bit de poids fort est 1 donc le signe est négatif
  • L'exposant est e = 2^{10}+2^2+2^1 - 1023 = 1030 - 1023 = 7
  • La mantisse est m = 1 + \frac{1}{2^1} + \frac{1}{2^3} + \frac{1}{2^5} + \frac{1}{2^6} + \frac{1}{2^8} + \frac{1}{2^9} = 1,677734375
  • Le nombre décimal représenté est -1,677734375 \times 2^7 = -214,75.

Valeurs particulières

Un certain nombre de codes sont réservés pour représenter des cas particuliers :

0 11111111111 0000000000000000000000000000000000000000000000000000

Ce code (0 suivi de onze 1, suivis de cinquante-deux 0) représente +\infty (+inf).

1 11111111111 0000000000000000000000000000000000000000000000000000

Ce code (1 suivi de onze 1, suivis de cinquante-deux 0) représente -\infty (-inf).

1 11111111111 1111111111111111111111111111111111111111111111111111

Ce code (soixante-quatre bits à 1) représente NaN (not a number).

0 00000000000 0000000000000000000000000000000000000000000000000000

Ce code (soixante-quatre bits à 0) représente 0.

1 00000000000 0000000000000000000000000000000000000000000000000000

Ce code (Un bit à 1 suivi de soixante-trois bits à 0) représente également 0 (-0).

Et dans l'autre sens?

Si l'on dispose du code de soixante-quatre bits représentant un flottant sous le format binary64 de la norme IEEE 754, il est facile d'en déduire le nombre représenté (il suffit d'appliquer la définition de ce format comme présenté plus haut).

Ce qui est moins évident est, connaissant un nombre réel, de savoir par quel flottant il va être représenté en machine.

Rappelons notamment qu'un même flottant représente en fait une infinité de réels distincts. Il y a également beaucoup de réels qui ne sont tout simplement pas représentables en machine suivant ce format (trop grand, ou trop proche de zéro).