Représentation des réels en machine

Cette partie explique tout d’abord les principales exigences que doit remplir une représentation des réels. Elle introduit ensuite le type de représentation des réels le plus classique, dit à virgule flottante. Elle présente enfin le format le plus courant de nombres à virgule flottante, le format binary64.

Exigences pour une représentation des réels en machine

Il existe des solutions pour représenter les réels de manière exacte en machine. Cependant, les contraintes de performance restreignent l’usage de ces méthodes au calcul formel. Les autres usages utilisent ainsi systématiquement des représentations approximatives des réels, qui sont les seules à remplir les exigences principales pour le calcul numérique, à savoir l’amplitude, la précision, et la performance.

Amplitude

L’amplitude d’une représentation correspond aux ordres de grandeur des nombres représentables. Il est nécessaire de pouvoir représenter à la fois des nombres très grands et très petits pour que les scientifiques s’y retrouvent.

En physique, par exemple, les ordres de grandeurs s’étalent entre 1080 (volume de l’univers observable, en mètres cubes) et 10-45 (volume d’un proton, en mètres cubes).

En mathématique, il est facile de générer des nombres encore plus extrêmes. Vous connaissez peut-être l’extrait de poème suivant.

Je fais souvent ce rêve étrange et pénétrant
D’une femme inconnue, et que j’aime, et qui m’aime,
[…]

« Mon rêve familier », Paul Verlaine

La probabilité de taper du premier coup ce texte de 105 caractères, espaces compris, en frappant aléatoirement les touches d’une machine à écrire, est de 45-105, soit environ 10-174. Si l’on considère le nombre de textes de 105 caractères que ce procédé peut générer, on trouve l’ordre de grandeur inverse, c’est-à-dire 10174.

Précision

La précision d’une représentation est encore plus importante que son amplitude. La précision correspond au nombre de chiffres significatifs qui peuvent être stockés.

En physique, les constantes connues avec le plus de précision ne dépassent pas la vingtaine de chiffres significatifs. Par exemple, la constante de Coulomb est connue avec 17 chiffres et la charge élémentaire avec environ 10 chiffres.

Ces deux constantes se côtoient dans les calculs d’électrostatique, mais n’ont pas du tout le même ordre de grandeur (109 pour la constante de Coulomb et 10-19 pour la charge élémentaire). Il est donc important que la représentation des réels utilisée garde la même précision quel que soit l’ordre de grandeur.

Performance

La performance correspond à la rapidité avec laquelle les calculs peuvent s’effectuer. Il est en effet hors de question d’attendre l’éternité pour obtenir un résultat. Il s’agit aussi d’être performant sur toutes les machines couramment utilisées.

La plupart des ordinateurs partagent la même architecture globale, conçue autour d’un processeur. Ce composant effectue des calculs en manipulant des groupes de bits de taille fixe appelés mots machine. La taille de ces mots est la caractéristique principale d’un processeur. On entend ainsi souvent parler de processeurs 64 bits ou 32 bits. Pour être le plus rapide possible, il est intéressant d’avoir un format de nombre pour lequel le câblage des opérations du processeur est performant. Cela passe par des compromis, notamment le fait de favoriser un format sur un seul mot machine.

Il existe différentes familles de représentation des réels qui remplissent les critères d’amplitude, précision et performance, mais la plus utilisée est sans conteste la représentation à virgule flottante.

Représentation des réels par les nombres à virgule flottante

L’idée générale des nombres à virgule flottante est de stocker les chiffres significatifs d’une part et l’ordre de grandeur d’autre part. Ils s’opposent aux nombres à virgule fixe, dont l’idée générale consiste à stocker tous les chiffres du nombre.

Rappel sur la notation scientifique

En base 10

En base 10, la notation scientifique d’un réel prend la forme suivante :

s×10es\times 10^{e}

avec :

  • ee un entier relatif, appelé exposant,
  • ss un réel, tel que 1s<101 \leq |s| < 10 ou s=0s = 0, appelé significande.

Le significande correspond aux chiffres significatifs (et au signe), tandis que l’exposant correspond à l’ordre de grandeur.

L’exposant et le significande sont suffisants pour définir un nombre en notation scientifique. Plus précisément, il suffit du signe du significande, de ses chiffres et de l’exposant. Il n’y a pas besoin de s’encombrer du chiffre 10 une fois que le choix d’utiliser la notation scientifique a été fait.

En base 2

En base 2, la notation scientifique d’un réel prend la forme suivante :

s×2es \times 2^e

avec :

  • ee un entier relatif, l'exposant,
  • ss un réel, tel que 1s<21 \leq |s| < 2 ou s=0s = 0, le significande.

Tout ça est évidemment très similaire à la notation en base 10. Le 10 se transforme en 2, et le significande se retrouve entre 1 et 2, au lieu d’être entre 1 et 10. Similairement, l’exposant, le significande et le signe suffisent à définir le nombre, sans besoin de s’encombrer du chiffre 2 une fois que le choix de la notation scientifique a été fait.

Nombres à virgule flottante

En informatique, un nombre à virgule flottante est tout simplement la donnée d’un significande et d’un exposant. Comme, il n’est pas trivial de stocker efficacement des chiffres en base 10, les représentations à virgule flottante généralement utilisées sont fondées sur la notation scientifique des nombres en base 2.

Stocker un nombre à virgule flottante est très simple, car il suffit de stocker les chiffres (binaires) du significande, son signe et l’exposant. Un seul bit suffit pour le signe, auquel on adjoint un certain nombre de bits pour stocker les chiffres du significande et l’exposant. Il n’y a pas besoin d’utiliser d’astuces ou de structures de données compliquées.

Vocabulaire

Les nombres à virgule flottante sont aussi appelés nombres flottants ou tout simplement flottants. C’est ce mot qui sera le plus souvent utilisé dans la suite du tutoriel.

Satisfaction des exigences de représentation des réels

Combien de bits sont nécessaires pour obtenir une amplitude et une précision satisfaisantes ? Pour le savoir, revenons un peu sur les ordres de grandeur.

Pour satisfaire l’amplitude, il faut stocker l’exposant, qui est un entier relatif. En calculant avec largesse, il suffit d’avoir quelques centaines d’entiers, pour ee entre -1000 et 1000 (dans la notation scientifique en base 2), on atteint des ordres de grandeurs entre 10-300 et 10300. Une petite dizaine de bits suffit donc, car 10 bits permettent déjà de stocker 210 = 1024 valeurs.

Pour satisfaire la précision, il faut stocker une petite quinzaine de chiffres en base 10. Cela correspond à une précision de l’ordre de 10-15 (15 décimales) sur le significande, soit de l’ordre de 2-50 (50 bits de partie fractionnaire). Il faut donc quelques dizaines de bits pour stocker le significande.

Par ailleurs, comme l’exposant et le significande sont stockés indépendamment, l’ordre de grandeur n’a aucune influence sur la précision du significande, ce qui est parfait pour les calculs mêlant divers ordres de grandeur.

En somme, il suffit de quelques dizaines de bits pour stocker tout le nécessaire, c’est-à-dire la taille des mots machine usuels. Par conséquent, on arrive à obtenir assez facilement une représentation performante des réels.

Le nombre et l’organisation exacte des bits formant un flottant sont définis dans ce qu’on appelle des formats de nombres à virgule flottante. Il existe différents formats standards, dont le plus utilisé est un format binaire sur 64 bits, qui est décrit plus en détails dans la prochaine section.

Le format de nombres à virgule flottante binary64

Au début de l’ère informatique, de nombreux formats de flottants coexistaient et étaient bien sûr incompatibles. Pour mettre fin au chaos, quelques formats standards ont été définis dans la norme IEEE 754. Le plus utilisé est le format binaire double précision, aussi appelé binary64.

Dans ce format, les flottants sont des nombres écrits en notation scientifique en base 2, sous la forme suivante :

±s×2e\pm s \times 2^{e}

avec les éléments suivants :

  • le signe, positif ou négatif ;
  • le significande ss, un réel positif tel que 1s<21 \leq s < 2 ;
  • l’exposant ee, un entier relatif.

Cette forme recouvre celle présentée dans la section précédente, sauf que j’ai séparé le signe, et donc le significande est toujours positif. Dans un cas très particulier, le significande pourra être inférieur à 1, mais nous reviendront dessus plus tard.

L’ensemble de ces éléments sont stockés sur 64 bits, dont :

  • un champ de 1 bit pour le signe,
  • un champ de 52 bits pour la partie fractionnaire de ss, appelée mantisse, c’est-à-dire les chiffres après la virgule uniquement,
  • un champ de 11 bits pour l’exposant.
Représentation des flottants 64 bits (schéma par GMjeanmatt, CC-BY-SA 3.0)
Représentation des flottants 64 bits (schéma par GMjeanmatt, CC-BY-SA 3.0)
Notation

Dans la suite de ce cours, les nombres en base 2 seront écrits entre crochets pour éviter la confusion avec la base 10. Par exemple, [10010100] est une représentation binaire et 10010100 une représentation décimale.

Les notations littérales, telles que ss et ee ne sont pas concernées, puisque la base n’a aucune influence sur la valeur d’un nombre. Les nombres 00 et 11 ne sont pas non plus concernés, car identiques en base 10 et en base 2.

Le bit de signe vaut 0 pour le signe plus et 1 pour le signe moins.

Le champ de 52 bits stocke uniquement la mantisse, c’est-à-dire la partie fractionnaire du significande. Pourquoi seulement la partie fractionnaire ? Eh bien, parce que la partie entière du significande est constante et égale à 1. En effet, le significande étant entre 1 et 2 exclu, il est de la forme [1,…]. Comme le champ fait 52 bits, cela signifie qu’on stocke 52 chiffres binaires après la virgule, auquel s’ajoute le bit fantôme de la partie entière.

Le champ de 11 bits restant code un entier relatif compris entre -1023 et 10241. Les valeurs entre -1022 et 1023 sont des valeurs d’exposant. Autrement dit, ee est entre -1022 et 1023. Les deux valeurs restantes sont des valeurs spéciales, utilisées pour deux cas particuliers :

  • Si le champ prend la valeur spéciale +1024, le flottant représente ±\pm \infty pour une mantisse nulle et un NaN sinon. NaN est l’acronyme de Not a Number, c’est-à-dire qu’il s’agit d’une valeur indéterminée, comme le résultat de 0×0 \times \infty.

  • Si le champ prend la valeur spéciale -1023, alors on rentre dans le domaine des nombres dénormalisés (voir encadré ci-dessous). De tous les dénormalisés, le seul important est zéro. Il est représenté avec le signe positif ou négatif (il y a deux zéros !), une mantisse nulle, et bien sûr l’exposant -1023.

Que sont les nombres dénormalisés ?

Lorsque l’exposant prend la valeur spéciale -1023, alors le bit implicite de la partie entière vaut 00 (au lieu de 1 habituellement), et l’exposant vaut -1022. Autrement dit, les nombres dénormalisés ont la forme suivante :

±[0,a1a52]×21022\pm [0{,}a_1 \dots a_{52}] \times 2^{-1022}

où les ana_n sont les bits de la mantisse qui prennent chacun la valeur zéro ou un.

La norme présente là une entorse astucieuse à la notation scientifique, qui permet de représenter des nombres beaucoup plus petits sans bit supplémentaire, mais avec une précision dégradée.

Si cela vous dépasse, retenez simplement qu’il y a des nombres « bizarres » en dessous de 210222^{-1022}, qui est le dernier nombre normal. Vous n’en rencontrerez quasiment jamais au cours de calculs usuels, si ce n’est 00.

Le tableau suivant contient quelques exemples de flottants.

Bit de signe Signe Bits d’exposant Valeur Bits de mantisse Significande Interprétation Commentaire
0 + 000 0000 0000 -1023 0…0 [0,0] +0+0 avec l’autre signe, on code 0-0
1 - 111 1111 1111 +1024 0…0 [0,0] -\infty avec l’autre signe, on code ++\infty
0 + 111 1111 1110 +1023 10…0 [1,1] +1,5×21023+1{,}5\times 2^{1023} nombre normalisé
0 + 111 1111 1110 +1023 010…0 [1,01] +1,25×21023+1{,}25\times 2^{1023} nombre normalisé

  1. La représentation biaisée des entiers relatifs est utilisée : les 11 bits codent un entier naturel entre 0 et 2047, auquel on soustrait 1023 pour obtenir le nombre relatif représenté.

Autres formats standards de nombres à virgule flottante

La norme IEEE 754 définit de nombreux autres formats à virgule flottante. Ils permettent d’avoir des flottants pour différentes tailles de mots machine (16, 32, 64, 128), voire carrément d’utiliser une représentation décimale, c’est-à-dire une véritable notation scientifique en base 10.

Formats binaires

Les formats binaires sont des formats où la mantisse est stockée sous forme binaire, c’est-à-dire la méthode classique. On peut remarquer que la mantisse prend une place toujours plus importante par rapport à l’exposant.

Nom Nom commun Bits de mantisse Bits d’exposants
binary16 Demie précision 10 5
binary32 Simple précision 23 8
binary64 Double précision 52 11
binary128 Quadruple précision 112 15

Format décimaux

Pour les formats décimaux, la mantisse est codée sous forme décimale binaire, c’est-à-dire que chaque chiffre décimal est représenté directement en binaire. Cette technique offre des avantages pour effectuer de manière exacte certains calculs (financiers par exemple), mais ce n’est pas l’objet de ce cours.

Nom Décimales Bits d’exposant1
decimal32 7 7,58
decimal64 16 9,58
decimal128 34 13,58

  1. Le nombre de bits de l’exposant est non entier, car le nombre de valeurs possibles n’est pas une puissance de deux. Par exemple, il y a 768 valeurs possibles pour le decimal64, soit log2(768)=9,58\log_2(768) = 9{,}58 bits.

Vous avez vu dans cette partie ce que sont les flottants et comment ils répondent aux impératifs d’amplitude, de précision et de performance pour le calcul scientifique.

Dans la partie suivante, vous verrez en quoi les flottants ne sont qu’une approximation des réels, ce qui vaut bien sûr aussi pour le format binary64.