Virgule flottante

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher
Le premier ordinateur programmable utilisant des nombres à points flottants Z3 (réplique au Deutsches Museum à Munich).
Un diagramme représentant un nombre à virgule flottante avec une mantisse et un exposant.

La virgule flottante est une méthode d'écriture de nombres réels fréquemment utilisée dans les ordinateurs.

Elle consiste à représenter un nombre par un signe s (égal à -1 ou 1), une mantisse m (aussi appelée significande) et un exposant e (entier relatif, généralement borné). Un tel triplet représente un réel s.m.beb est la base de représentation (généralement 2 sur ordinateur, mais aussi 16 sur certaines anciennes machines, 10 sur de nombreuses calculatrices, ou éventuellement toute autre valeur). En faisant varier e, on fait « flotter » la virgule décimale. La mantisse m est représentée par une suite de chiffres en base b, généralement de taille fixée, dans laquelle on choisit de placer une virgule à une position fixe: juste avant ou juste après le premier chiffre, ou juste après le dernier chiffre; dans ce dernier cas, la mantisse est un entier naturel. Pour un nombre donné, la valeur de l'exposant dépend de ce choix. Les nombres en virgule flottante peuvent ainsi être vus comme l'équivalent informatique de la notation scientifique, qui correspond à la deuxième convention (virgule placée juste après le premier chiffre).

Ceci s'oppose à la représentation dite en virgule fixe, où l'exposant e est fixé.

L'avantage de la représentation en virgule flottante par rapport à la virgule fixe ou à l'entier, est que la virgule flottante est capable, à nombre de bits égal, de gérer un intervalle de nombres réels plus important. Par exemple, une représentation en virgule fixe qui a sept chiffres décimaux et fixée à deux chiffres après la virgule peut représenter les nombres 12345.67, 123.45, 1.23, etc. La représentation en virgule flottante (comme le format IEEE 754 decimal32) peut quant à elle, avec sept chiffres décimaux, représenter en plus 1.234567, 123456.7 = 1.234567 × 105, 0.00001234567 = 1.234567 × 10-5, 1234567000000000 = 1.234567 × 1015, etc.

En revanche, le format à virgule flottante occupe un peu plus de place, car il est nécessaire d'encoder la position de la virgule (représentée par l'exposant). Pour le même espace disponible, la virgule flottante offre donc une étendue de nombres plus grande au détriment de la précision.

La vitesse des opérations en virgule flottante, communément appelée FLOPS dans les mesures de performances, est une caractéristique importante des machines, en particulier dans les logiciels qui effectuent des calculs mathématiques à grande échelle.

Au cours des ans, un certain nombre de représentations à virgule flottante a vu le jour, ce qui constituait un frein au portage des programmes de calcul scientifique d'une machine à l'autre, en raison des différences de représentations internes et de comportement des nombres flottants. Pour cette raison, une norme a finalement été mise en place par l'IEEE en 1985 : IEEE 754.

Mises en œuvre[modifier | modifier le code]

Norme IEEE 754[modifier | modifier le code]

Article détaillé : IEEE 754.

La norme IEEE 754 de 1985 (reprise par la norme internationale CEI 60559) spécifie deux formats de nombres en virgule flottante (et deux formats étendus optionnels) en base 2, ainsi que quelques opérations associées: principalement l'addition, la soustraction, la multiplication, la division et la racine carrée. La quasi-totalité des architectures d'ordinateurs actuelles, y compris IA32, PowerPC, et AMD64, incluent une implémentation matérielle des calculs sur flottants IEEE, directement dans le microprocesseur, garantissant une exécution rapide.

Les deux formats fixés par la norme IEEE 754 sont sur 32 bits (« simple précision », maintenant appelé binary32) et 64 bits (« double précision », maintenant appelé binary64). La répartition des bits est la suivante, où 1 ≤ M < 2 :

Précision Encodage Signe Exposant Mantisse Valeur d'un nombre Précision Chiffres significatifs
Simple précision 32 bits 1 bit 8 bits 23 bits (-1)^S \times M \times 2^{(E-127)} 24 bits environ 7
Double précision 64 bits 1 bit 11 bits 52 bits (-1)^S \times M \times 2^{(E-1023)} 53 bits environ 16

Le tableau ci-dessus indique les bits représentés. Le premier bit de la mantisse d'un nombre normalisé étant toujours 1, il n'est représenté dans aucun de ces deux formats : on parle de bit implicite. Pour ces deux formats, les précisions sont donc respectivement de 24 et de 53 bits. Deux valeurs du champ Exposant sont réservées pour encoder les nombres spéciaux: nombres dénormalisés et zéro signé d'une part, les infinis et les NaN (Not-a-Number) d'autre part.

En plus de la représentation, la norme spécifie exactement le comportement des opérations supportées: celles-ci doivent être correctement arrondies dans un des 4 modes d'arrondi choisi.

Cette norme a été révisée dans les années 2000 pour aboutir à la publication d'une nouvelle norme en 2008. De nouveaux formats ont été définis (« quadruple précision » ou binary128, et des formats décimaux), la notion de format étendu a été généralisée, et de nouvelles opérations ont été ajoutées, comme le FMA; les principales fonctions élémentaires sont recommandées.

Flottants étendus[modifier | modifier le code]

Certaines implémentations ajoutent un ou plusieurs formats de précision supérieure (ainsi, IA32 a un format étendu sur 80 bits). La norme IEEE 754-1985 prévoit des tailles minimales pour ces formats étendus :

Précision Signe Exposant Mantisse
Simple précision étendue 1 bit 11 bits ou plus 32 bits ou plus
Double précision étendue 1 bit 15 bits ou plus 64 bits ou plus

Ces représentations « étendues » n'utilisent pas forcément le bit implicite de la mantisse.

Dans la pratique, seule la double précision étendue est encore utilisée, dans sa forme minimale (1+15+64 = 80 bits, le fameux format étendu de l'IA32).

Lorsque les flottants IEEE offrent une précision insuffisante, on peut devoir recourir à des calculs sur des flottants en précision supérieure. Citons notamment la bibliothèque GNU MPFR.

Précautions d'emploi[modifier | modifier le code]

Les calculs en virgule flottante sont pratiques, mais présentent divers désagréments, notamment :

  • leur précision limitée, qui se traduit par des arrondis (dus aux opérations, ainsi qu'aux changements de base implicites, si la base est différente de 10) qui peuvent s'accumuler de façon gênante. En particulier, la soustraction de deux nombres très proches et entachés d'erreur provoque une grande perte de précision relative : on parle de « cancellation ».
  • une plage d'exposants limitée, pouvant donner lieux à des « overflows » (lorsque le résultat d'une opération est plus grand que la plus grande valeur représentable) et à des « underflows » (lorsqu'un résultat est plus petit, en valeur absolue, que le plus petit flottant normalisé positif), puis à des résultats n'ayant plus aucun sens.

Il est par exemple tentant de réorganiser des expressions en virgule flottante comme on le ferait d'expressions mathématiques. Cela n'est cependant pas anodin, car les calculs en virgule flottante, contrairement aux calculs sur les réels, ne sont pas associatifs. Par exemple, dans un calcul en flottants IEEE double précision, (260+1)-260 ne donne pas 1, mais 0 (en arrondi au plus près). La raison est que 260+1 n'est pas représentable exactement et est arrondi à 260.

En arithmétique flottante IEEE, un calcul peut aboutir à des valeurs qui ne correspondent pas à des nombres réels :

  • NaN (« not a number »), qui sera par exemple le résultat de la tentative de division flottante de zéro par zéro, ou de la racine carrée d'un nombre strictement négatif. Les NaN se propagent : la plupart des opérations faisant intervenir un NaN donnent NaN (des exceptions sont possibles, comme NaN puissance 0, qui peut donner 1).
  • Un infini positif et un infini négatif, qui sont par exemple le résultat d'un « overflow » en arrondi au plus près.

Voir aussi[modifier | modifier le code]

Articles connexes[modifier | modifier le code]

Liens externes[modifier | modifier le code]