En informatique, l’IEEE 754 est une norme sur l'arithmétique à virgule flottante mise au point par le Institute of Electrical and Electronics Engineers. Elle est la norme la plus employée actuellement pour le calcul des nombres à virgule flottante avec les CPU et les FPU. La norme définit les formats de représentation des nombres à virgule flottante (signe, mantisse, exposant, nombres dénormalisés) et valeurs spéciales (infinis et NaN), en même temps qu’un ensemble d’opérations sur les nombres flottants. Il décrit aussi cinq modes d'arrondi et cinq exceptions (comprenant les conditions dans lesquelles une exception se produit, et ce qui se passe dans ce cas).
La version d'origine de la norme IEEE 754, datant de 1985, définissait quatre formats pour représenter des nombres à virgule flottante en base 2 :
Par exemple, dans le langage C, le compilateur gcc pour les architectures compatibles Intel 32 bits utilise le format simple précision pour les variables de type float, double précision pour les variables de type double, et la double précision ou la double précision étendue (suivant le système d'exploitation) pour les variables de type long double. Cependant, si l'extension SSE2 n'est pas utilisée, tous les calculs sont arrondis à la même précision, suivant la configuration de la précision dynamique du processeur (en général, double précision ou double précision étendue, suivant le système d'exploitation, les options de compilation, et les changements effectués par les programmes).
Le titre complet de la norme était IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985) (norme IEEE pour l'arithmétique binaire en virgule flottante). Elle est aussi connue sous le nom IEC 60559:1989, Binary floating-point arithmetic for microprocessor systems[1], ce qui en fait aussi une norme (américaine), approuvée depuis comme référence normative dans plusieurs normes internationales de l’ISO.
Cependant cette norme a été étendue par une révision majeure en 2008 à d‘autres formats de base (binaire sur 128 bits et décimaux sur 64 et 128 bits) ainsi que des formats d'échange (ajoutant des formats soit moins précis, soit plus précis) et des formats étendus (généralisation de la norme de 1985, avec plus de liberté sur la précision et l'encodage qu'avec les formats d'échange)[2] ; cette révision inclut également des modes d'arrondis supplémentaires et des exigences de conformité plus poussées concernant la précision attendue des opérations et calculs de fonctions transcendantes de base. Cette norme a également été révisée en 2019.
Dans un mot de longueur W, les bits sont indexés de 0 à W−1, inclus. Le bit 0 est placé à droite, il représente le bit de poids faible (c’est-à-dire le bit des unités, qui provoque la plus petite variation quand il est modifié).
Un nombre flottant est formé de trois éléments : la mantisse, l'exposant et le signe. Le bit de poids fort est le bit de signe : si ce bit est à 1, le nombre est négatif, et s’il est à 0, le nombre est positif. Les e bits suivants représentent l'exposant biaisé (sauf valeur spéciale), et les m bits suivants (m bits de poids faible) représentent la mantisse.
Signe | Exposant biaisé | Mantisse |
(1 bit) | (e bits) | (m bits) |
L'exposant peut être positif ou négatif. Cependant, la représentation habituelle des nombres signés (complément à 2) rendrait la comparaison entre les nombres flottants un peu plus difficile. Pour régler ce problème, l'exposant est « biaisé », afin de le stocker sous forme d'un nombre non signé.
Ce biais est de 2e−1 − 1 (e représente le nombre de bits de l'exposant) ; il s'agit donc d'une valeur constante une fois que le nombre de bits e est fixé.
L'interprétation d'un nombre (autre qu'infini) est donc : valeur = signe × mantisse × 2(exposant − biais) avec
Le bit de poids fort de la mantisse est déterminé par la valeur de l'exposant biaisé. Si l'exposant biaisé est différent de 0 et de , le bit de poids fort de la mantisse est 1, et le nombre est dit « normalisé ». Si l'exposant biaisé est nul, le bit de poids fort de la mantisse est nul, et le nombre est dénormalisé.
Il y a trois cas particuliers :
Nous pouvons le résumer ainsi :
Type | Exposant biaisé | Mantisse |
---|---|---|
Zéros | 0 | 0 |
Nombres dénormalisés | 0 | différente de 0 |
Nombres normalisés | à | quelconque |
Infinis | 0 | |
NaNs | différente de 0 |
Un nombre flottant simple précision est stocké dans un mot de 32 bits : 1 bit de signe, 8 bits pour l'exposant et 23 pour la mantisse.
L'exposant est donc biaisé de dans ce cas. L'exposant d'un nombre normalisé va donc de -126 à +127. L'exposant -127 (qui est biaisé vers la valeur 0) est réservé pour zéro et les nombres dénormalisés, tandis que l'exposant 128 (biaisé vers 255) est réservé pour coder les infinis et les NaN (voir le tableau précédent).
Un nombre flottant normalisé a une valeur v donnée par la formule suivante :
Par exemple pour 0b 0 01111100 01000000000000000000000 : le signe est positif, l'exposant est 124 − 127 = −3, et la partie significative est 0b 1,01 soit 1,25 en décimal (1 × 20 + 0× 2−1 + 1 × 2−2) ; le nombre représenté est donc +1,25 × 2−3 soit +0,15625.
Les nombres dénormalisés suivent le même principe, sauf que e = −126 et m = 0+mantisse (attention : pour le calcul, on veillera à prendre e = −126 et non −127, ceci afin de garantir la continuité de cette représentation avec la représentation normalisée, puisque m = 0+mantisse et non plus m = 1+mantisse).
Remarques :
Voici un tableau résumant la partie précédente, avec des exemples de nombres 32 bits simple précision.
Type | Exposant | Mantisse | Valeur approchée | Écart / préc |
---|---|---|---|---|
Zéro | 0000 0000 | 000 0000 0000 0000 0000 0000 | 0,0 | |
Plus petit nombre dénormalisé | 0000 0000 | 000 0000 0000 0000 0000 0001 | 1,4 × 10−45 | 1,4 × 10−45 |
Nombre dénormalisé suivant | 0000 0000 | 000 0000 0000 0000 0000 0010 | 2,8 × 10−45 | 1,4 × 10−45 |
Nombre dénormalisé suivant | 0000 0000 | 000 0000 0000 0000 0000 0011 | 4,2 × 10−45 | 1,4 × 10−45 |
Autre nombre dénormalisé | 0000 0000 | 100 0000 0000 0000 0000 0000 | 5,9 × 10−39 | |
Plus grand nombre dénormalisé | 0000 0000 | 111 1111 1111 1111 1111 1111 | 1,175 494 21 × 10−38 | |
Plus petit nombre normalisé | 0000 0001 | 000 0000 0000 0000 0000 0000 | 1,175 494 35 × 10−38 | 1,4 × 10−45 |
Nombre normalisé suivant | 0000 0001 | 000 0000 0000 0000 0000 0001 | 1,175 494 49 × 10−38 | 1,4 × 10−45 |
Presque le double | 0000 0001 | 111 1111 1111 1111 1111 1111 | 2,350 988 56 × 10−38 | 1,4 × 10−45 |
Nombre normalisé suivant | 0000 0010 | 000 0000 0000 0000 0000 0000 | 2,350 988 70 × 10−38 | 1,4 × 10−45 |
Nombre normalisé suivant | 0000 0010 | 000 0000 0000 0000 0000 0001 | 2,350 988 98 × 10−38 | 2,8 × 10−45 |
Presque 1 | 0111 1110 | 111 1111 1111 1111 1111 1111 | 0,999 999 94 | 0,6 × 10−7 =2−24 |
1 | 0111 1111 | 000 0000 0000 0000 0000 0000 | 1,000 000 00 | |
Nombre suivant 1 | 0111 1111 | 000 0000 0000 0000 0000 0001 | 1,000 000 12 | 1,2 × 10−7 =2−23 |
Presque le plus grand nombre | 1111 1110 | 111 1111 1111 1111 1111 1110 | 3,402 823 26 × 1038 | |
Plus grand nombre normalisé | 1111 1110 | 111 1111 1111 1111 1111 1111 | 3,402 823 46 × 1038 | 2 × 1031 |
Infini | 1111 1111 | 000 0000 0000 0000 0000 0000 | Infini | |
Première valeur (dénormalisée) de NaN avertisseur | 1111 1111 | 000 0000 0000 0000 0000 0001 | NaN | |
NaN normalisé (avertisseur) | 1111 1111 | 010 0000 0000 0000 0000 0000 | NaN | |
Dernière valeur (dénormalisée) de NaN avertisseur | 1111 1111 | 011 1111 1111 1111 1111 1111 | NaN | |
Première valeur (dénormalisée) de NaN silencieux | 1111 1111 | 100 0000 0000 0000 0000 0000 | NaN | |
Dernière valeur (dénormalisée) de NaN silencieux | 1111 1111 | 111 1111 1111 1111 1111 1111 | NaN |
Notes :
Codons le nombre décimal −118,625 en utilisant le mécanisme IEEE 754.
On a donc −118,625 (dec) = 1100 0010 1110 1101 0100 0000 0000 0000 (bin) = C2ED4000 (hexa).
Le format double précision est similaire au simple précision, mis à part le fait que les champs sont plus grands. En effet, il possède 52 bits de mantisse au lieu de seulement 23, et 11 bits d'exposant au lieu de seulement 8.
La mantisse est très élargie, alors que l'exposant est peu élargi. Ceci est dû au fait que, selon les créateurs de la norme, la précision est plus importante que l'amplitude.
Les NaN et les infinis sont représentés en mettant tous les bits de l'exposant à 1 (2047), mais distingués en mettant la totalité des 52 bits de la mantisse à 0 pour les infinis et au moins un de ces 52 bits à 1 pour les NaN.
Pour les nombres normalisés, le biais de l'exposant est +1023. Pour les nombres dénormalisés, l'exposant est −1022 (l'exposant minimum pour un nombre normalisé). Ce n'est pas −1023 car les nombres normalisés ont un 1 avant la virgule, et les nombres dénormalisés n'en ont pas. Comme précédemment, zéro et l'infini sont signés.
Remarques :
Il est généralement préférable de comparer des nombres flottants en utilisant les instructions de calcul flottant. Cependant, cette représentation rend les comparaisons de certains sous-ensembles possible octet par octet, s’ils ont le même ordre d'octets et le même signe, et que les NaNs sont exclus.
Par exemple, pour deux nombres flottants positifs a et b, la comparaison entre a et b (>, <, ou ==) donne les mêmes résultats que la comparaison de deux nombres signés (ou non signés) avec les mêmes bits que a et b. En d'autres mots, deux nombres flottants positifs (qui ne sont pas des NaN) peuvent être comparés avec une comparaison binaire signée (ou non signée). Cependant selon les processeurs et à cause de leur convention d'ordre des octets, les comparaisons (> ou <) ne doivent pas être utilisées dans du code portable.
La norme IEEE spécifie 5 modes d'arrondi :
En , une révision majeure des normes IEEE 754 et IEEE 854 a été approuvée par l'IEEE. Voir : IEEE 754-2008 (en)[4],[5].
Cette révision apporte de nouveaux formats en base 2 et en base 10, et spécifie la représentation des formats en base 10 (en plus de la base 2). Plus précisément, elle définit cinq formats de base qui sont nommés d'après leur base (binaire ou décimale) et le nombre total de bits utilisés dans leur codage. Il y a trois formats de base binaires en virgule flottante (codés sur 32, 64 ou 128 bits) et deux formats de base décimaux en virgule flottante (codés sur 64 ou 128 bits). Les formats binary32 et binary64 sont les formats simple et double précision de la norme IEEE 754-1985. Elle définit également des formats d'échange, qui généralisent ces formats de base. Pour les formats binaires, la convention sur le bit de poids fort est nécessaire. Le tableau ci-dessous résume les caractéristiques des formats de base et des plus petits formats d'échange.
Nom | Nom usuel | Base | Nb. chiffres de la mantisse[note 1] | Nb. chiffres décimaux[note 2] | Nb. bits exposant | log10 MAX | Exposant biaisé[6] | E min | E max | Type |
---|---|---|---|---|---|---|---|---|---|---|
binary16 | Demi-précision | 2 | 11 | 3.31 | 5 | 4.816 | 24−1 = 15 | −14 | +15 | Échange |
binary32 | Simple précision | 2 | 24 | 7.22 | 8 | 38.532 | 27−1 = 127 | −126 | +127 | Binaire basique |
binary64 | Double précision | 2 | 53 | 15.95 | 11 | 308.255 | 210−1 = 1023 | −1022 | +1023 | Binaire basique |
binary128 (en) | Quadruple précision | 2 | 113 | 34.02 | 15 | 4932.075 | 214−1 = 16383 | −16382 | +16383 | Binaire basique |
binary256 (en) | Octuple précision | 2 | 237 | 71.34 | 19 | 78913.207 | 218−1 = 262143 | −262142 | +262143 | Échange |
decimal32 (en) | 10 | 7 | 7 | 7.58 | 97.000 | 101 | −95 | +96 | Échange | |
decimal64 (en) | 10 | 16 | 16 | 9.58 | 385.000 | 398 | −383 | +384 | Décimal basique | |
decimal128 (en) | 10 | 34 | 34 | 13.58 | 6145.000 | 6176 | −6143 | +6144 | Décimal basique |
Elle normalise également une relation d’ordre total pour chacun des types de données numériques normalisés, en complétant les relations d’ordre habituelles qui ne sont que partielles ; en effet la relation d'ordre normale n’est totale qu'à condition de supprimer de l’ensemble de valeurs, la valeur zéro négative (normalement comparée comme égale à la valeur zéro positive) et toutes les valeurs NaN (qui ne sont ni égales, ni supérieures, ni inférieures à aucune autre, pas même elles-mêmes).
En revanche, cette révision laisse la flexibilité de représentation et de distinction éventuelle des valeurs NaN (la position et la valeur du ou des bits d’avertissement dans le champ mantisse ne sont pas normalisées, et l’utilisation des autres bits du champ mantisse ou de signe d’une valeur NaN pour codifier une erreur reste dépendante de l’architecture ou des applications).
Une nouvelle révision a été approuvée en .