Un des premiers ordinateurs programmables électromécaniques, le Z3 , comprenait l'arithmétique à virgule flottante (une réplique est exposée au Deutsches Museum de Munich ). En ...
Worldlex WikiContenu en francaisLecture gratuite
Un des premiers ordinateurs programmables électromécaniques, le Z3 , comprenait l'arithmétique à virgule flottante (une réplique est exposée au Deutsches Museum de Munich ).informatique , l'arithmétique à virgule flottante ( AF ) est une arithmétique qui s'effectue sur des sous-ensembles de nombres réels formés par la mantisse (une séquence signée d'un nombre fixe de chiffres dans une base donnée ) multipliée par une puissance entière de cette base. Les nombres de cette forme sont appelés nombres à virgule flottante .
Par exemple, 2469/200 est un nombre à virgule flottante en base dix à cinq chiffres. En revanche, 7716/625 = 12,3456 n'est pas un nombre à virgule flottante en base dix à cinq chiffres ; il lui en faut six. Le nombre à virgule flottante le plus proche à cinq chiffres est 12,346. Et 1/3 = 0,3333… n'est pas un nombre à virgule flottante en base dix avec un nombre fini de chiffres. En pratique, la plupart des systèmes à virgule flottante utilisent la base deux , bien que la base dix ( nombre à virgule flottante décimal ) soit également courante.
Les opérations arithmétiques en virgule flottante, telles que l'addition et la division, approchent les opérations arithmétiques correspondantes sur les nombres réels en arrondissant tout résultat qui n'est pas lui-même un nombre en virgule flottante à un nombre en virgule flottante proche. Par exemple, dans une arithmétique en virgule flottante avec cinq chiffres en base dix, la somme 12,345 + 1,0001 = 13,3451 pourrait être arrondie à 13,345.
Le terme « virgule flottante » fait référence au fait que la virgule du chiffre des unités peut se situer n'importe où à gauche, à droite ou entre les chiffres significatifs du nombre. Cette position est indiquée par l'exposant ; la virgule flottante peut donc être considérée comme une forme de notation scientifique .
Un système à virgule flottante permet de représenter, avec un nombre fixe de chiffres, des nombres d' ordres de grandeur très différents , comme la distance entre les galaxies ou entre les protons d'un atome . C'est pourquoi l'arithmétique à virgule flottante est souvent utilisée pour représenter des nombres réels très petits et très grands, nécessitant des temps de traitement rapides. Cette large plage dynamique implique que les nombres représentables ne sont pas uniformément espacés ; la différence entre deux nombres consécutifs représentables varie selon leur exposant.
Nombres à virgule flottante simple précision sur une droite numérique : les lignes vertes indiquent les valeurs représentables.Version augmentée ci-dessus montrant les deux signes de valeurs représentables
Au fil des années, diverses représentations des nombres à virgule flottante ont été utilisées en informatique. En 1985, la norme IEEE 754 relative à l'arithmétique à virgule flottante a été établie, et depuis les années 1990, les représentations les plus courantes sont celles définies par l'IEEE.
La vitesse des opérations en virgule flottante, généralement mesurée en FLOPS , est une caractéristique importante d'un système informatique , notamment pour les applications impliquant des calculs mathématiques intensifs.
Les nombres à virgule flottante peuvent être calculés par logiciel (flux flottant souple) ou par matériel (flux flottant dur). Les unités de calcul en virgule flottante (FPU, communément appelées coprocesseurs mathématiques ) sont spécialement conçues pour effectuer des opérations sur les nombres à virgule flottante et sont présentes dans la plupart des systèmes informatiques. En l'absence de FPU, des implémentations logicielles peuvent être utilisées.
représentation numérique spécifie une manière d'encoder un nombre, généralement sous forme de chaîne de chiffres.
Il existe plusieurs mécanismes permettant de représenter des nombres par des chaînes de chiffres. En notation mathématique standard, la longueur d'une chaîne de chiffres est quelconque, et la position de la virgule est indiquée par un point ou une virgule. Si la virgule n'est pas spécifiée, la chaîne représente implicitement un entier , et la virgule se situe alors à droite de la chaîne, près du chiffre le moins significatif. Dans les systèmes à virgule fixe , la position de la virgule est spécifiée dans la chaîne. Ainsi, un système à virgule fixe peut utiliser une chaîne de 8 chiffres décimaux avec la virgule au milieu, de sorte que « 00012345 » représente 0001,2345.
En notation scientifique , le nombre donné est élevé à une puissance de 10 afin de se situer dans un intervalle précis, généralement entre 1 et 10, la virgule étant placée juste après le premier chiffre. Le facteur d'élévation, exprimé en puissance de dix, est ensuite indiqué séparément à la fin du nombre. Par exemple, la période orbitale de Io , lune de Jupiter , est de 1/10.. Cette chaîne de chiffres est appelée mantisse ou coefficient . La longueur de la mantisse détermine la précision de la représentation des nombres. La position de la virgule est toujours supposée se situer à l'intérieur de la mantisse, généralement juste après ou juste avant le chiffre le plus significatif, ou à droite du chiffre le moins significatif. Cet article suit généralement la convention selon laquelle la virgule est placée juste après le chiffre le plus significatif (le plus à gauche).
Un exposant entier signé (également appelé caractéristique ou échelle ), qui modifie la magnitude du nombre.
Pour obtenir la valeur du nombre à virgule flottante, la mantisse est multipliée par la base élevée à la puissance de l' exposant , ce qui équivaut à déplacer la virgule de la base par rapport à sa position implicite d'un nombre de places égal à la valeur de l'exposant — vers la droite si l'exposant est positif ou vers la gauche si l'exposant est négatif.
En utilisant la base 10 (la notation décimale familière ) comme exemple, le nombre
La manière dont la mantisse (y compris son signe) et l'exposant sont stockés dans un ordinateur dépend de l'implémentation. Les formats IEEE courants sont décrits en détail plus loin et ailleurs, mais à titre d'exemple, dans la représentation binaire à virgule flottante simple précision (32 bits) , la mantisse est une chaîne de 24 bits . Par exemple, les 33 premiers bits du nombre π sont :
Dans ce développement binaire, notons les positions de 0 (bit le plus à gauche, ou bit de poids fort) à 32 (bit le plus à droite). La mantisse de 24 bits s'arrête à la position 23, représentée par le bit souligné.des règles spécifiques pour les valeurs intermédiaires , ce qui n'est pas le cas ici). Ce bit, qui est
Lorsqu'elle est stockée en mémoire selon le codage IEEE 754, cette valeur devient la mantisse
où La représentation à virgule fixe utilise des opérations matérielles sur les entiers, contrôlées par une implémentation logicielle qui définit une convention spécifique concernant la position de la virgule binaire ou décimale (par exemple, à 6 bits ou chiffres de la droite). Le matériel nécessaire à la manipulation de ces représentations est moins coûteux que celui utilisé pour la virgule flottante, et il permet également d'effectuer des opérations sur les entiers classiques. La virgule fixe binaire est généralement employée dans des applications spécialisées sur des processeurs embarqués capables uniquement d'effectuer des calculs sur des entiers, tandis que la virgule fixe décimale est courante dans les applications commerciales.
Les systèmes de numération logarithmiques (SNL) représentent un nombre réel par le logarithme de sa valeur absolue et un bit de signe. La distribution des valeurs est similaire à celle des nombres à virgule flottante, mais la courbe de représentation ( c'est -à- dire le graphe de la fonction logarithme) est lisse (sauf en 0). Contrairement à l'arithmétique à virgule flottante, dans un SNL, la multiplication, la division et l'exponentiation sont simples à implémenter, mais l'addition et la soustraction sont complexes. L' arithmétique à niveaux et indices (LI et SLI) symétrique de Charles Clenshaw, Frank Olver et Peter Turner est un schéma basé sur une représentation logarithmique généralisée .
Certains nombres rationnels simples ( par exemple , 1/3 et 1/10) ne peuvent être représentés exactement en binaire à virgule flottante, quelle que soit la précision. L'utilisation d'une base différente permet d'en représenter certains ( par exemple , 1/10 en décimal à virgule flottante), mais les possibilités restent limitées. Les logiciels effectuant des calculs sur les nombres rationnels les représentent sous forme de fractions dont le numérateur et le dénominateur sont des entiers, et peuvent donc représenter n'importe quel nombre rationnel exactement. Ces logiciels utilisent généralement l'arithmétique des grands nombres pour les entiers individuels.
L'arithmétique d'intervalles permet de représenter les nombres sous forme d'intervalles et d'obtenir des bornes garanties sur les résultats. Elle repose généralement sur d'autres arithmétiques, notamment l'arithmétique à virgule flottante.
Les systèmes de calcul formel tels que Mathematica , Maxima et Maple peuvent souvent traiter les nombres irrationnels comme √3 ou √4 de manière totalement formelle ( calcul symbolique ), sans avoir à se soucier d'un encodage spécifique de la mantisse. Un tel programme peut évaluer des expressions comme « √3 » exactement, car il est programmé pour traiter directement les opérations mathématiques sous-jacentes, au lieu d'utiliser des valeurs approchées pour chaque calcul intermédiaire.
En 1914, l'ingénieur espagnol Leonardo Torres Quevedo publia ses Essais sur l'automatique , où il concevait une calculatrice électromécanique spécialisée, basée sur la machine analytique de Charles Babbage , et décrivait une méthode de stockage cohérent des nombres à virgule flottante. Il affirmait que les nombres seraient stockés sous forme exponentielle et proposait trois règles permettant une manipulation cohérente des nombres à virgule flottante par les machines. Pour Torres, « n aura toujours le même nombre de chiffres (par exemple six), le premier chiffre de n sera de l'ordre des dixièmes, le second des centièmes, etc., et chaque quantité s'écrira sous la forme : n ; m ». Le format qu'il propose montre la nécessité d'une mantisse de taille fixe, comme c'est le cas actuellement pour les données à virgule flottante, fixant ainsi l'emplacement de la virgule décimale dans la mantisse afin que chaque représentation soit unique, et comment formater de tels nombres en spécifiant une syntaxe à utiliser qui pourrait être saisie à l'aide d'une machine à écrire , comme c'était le cas pour son arithmomètre électromécanique en 1920.
Konrad Zuse , architecte de l' ordinateur Z3 , qui utilise une représentation binaire à virgule flottante de 22 bits
En 1938, Konrad Zuse, de Berlin, acheva le Z1 , le premier ordinateur mécanique binaire programmable ; il utilise une représentation binaire des nombres à virgule flottante sur 24 bits avec un exposant signé sur 7 bits, une mantisse sur 17 bits (dont un bit implicite) et un bit de signe. Le Z3 , plus fiable et basé sur des relais , achevé en 1941, possède des représentations pour les infinis positifs et négatifs ; en particulier, il implémente des opérations définies avec l’infini, telles que la division par l’infini , où , et s’arrête sur les opérations non définies, telles que .
Zuse a également proposé, sans toutefois la finaliser, une arithmétique à virgule flottante soigneusement arrondie incluant les représentations de 0 et 1, anticipant ainsi de quatre décennies certaines caractéristiques de la norme IEEE. À l'inverse, von Neumann a déconseillé l'utilisation de nombres à virgule flottante pour la machine IAS de 1951 , arguant que l'arithmétique à virgule fixe était préférable.
Le premier ordinateur commercial doté de matériel à virgule flottante fut l'ordinateur Z4 de Zuse , conçu entre 1942 et 1945. En 1946, les laboratoires Bell ont introduit le modèle V , qui implémentait des nombres décimaux à virgule flottante .
Le Pilot ACE, doté d'une arithmétique binaire à virgule flottante, est devenu opérationnel en 1950 au National Physical Laboratory (Royaume-Uni) . Trente-trois exemplaires ont ensuite été commercialisés sous le nom d' English Electric DEUCE . Bien que l'arithmétique soit implémentée par logiciel, sa fréquence d'horloge de 1 MHz lui conférait initialement une vitesse d'exécution des opérations en virgule flottante et en virgule fixe supérieure à celle de nombreux ordinateurs concurrents.
L' IBM 704, produit en masse, suivit en 1954 ; il introduisit l'utilisation d'un exposant biaisé . Pendant plusieurs décennies, le matériel dédié au calcul en virgule flottante était généralement une option, et les ordinateurs qui en étaient équipés étaient qualifiés d'« ordinateurs scientifiques » ou possédaient des capacités de « calcul scientifique » (CS) (voir aussi Extensions pour le calcul scientifique (XSC)). Ce n'est qu'avec le lancement de l'Intel i486 en 1989 que les ordinateurs personnels à usage général intégrèrent le calcul en virgule flottante de série.
La série UNIVAC 1100/2200 , introduite en 1962, prenait en charge deux représentations à virgule flottante :
Précision simple : 36 bits, organisés comme un signe de 1 bit, un exposant de 8 bits et une mantisse de 27 bits.
Double précision : 72 bits, organisés en un signe de 1 bit, un exposant de 11 bits et une mantisse de 60 bits.
L' IBM 7094 , également lancé en 1962, prenait en charge les représentations en simple et double précision, mais sans aucun lien avec celles de l'UNIVAC. En 1964, IBM introduisit les représentations hexadécimales à virgule flottante dans ses ordinateurs centraux System/360 ; ces mêmes représentations sont toujours disponibles pour les systèmes modernes d'architecture z . En 1998, IBM implémenta l'arithmétique binaire à virgule flottante conforme aux normes IEEE dans ses ordinateurs centraux ; en 2005, IBM ajouta également l'arithmétique décimale à virgule flottante conforme aux normes IEEE.
Initialement, les ordinateurs utilisaient diverses représentations des nombres à virgule flottante. Le manque de standardisation au niveau des ordinateurs centraux constituait un problème persistant au début des années 1970 pour les développeurs et les mainteneurs de code source de haut niveau. Les normes de représentation des nombres à virgule flottante des différents constructeurs différaient en termes de taille des mots, de représentation, de comportement d'arrondi et de précision générale des opérations. La compatibilité des nombres à virgule flottante entre les différents systèmes informatiques nécessitait une standardisation urgente au début des années 1980, ce qui a conduit à la création de la norme IEEE 754 une fois que le mot de 32 bits (ou 64 bits) s'est généralisé. Cette norme s'inspirait largement d'une proposition d'Intel, qui concevait le coprocesseur numérique i8087 ; Motorola, qui concevait le 68000 à la même époque, y a également apporté une contribution significative.
En 1989, le mathématicien et informaticien William Kahan a reçu le prix Turing pour avoir été le principal architecte de cette proposition ; il a été aidé par son étudiant Jerome Coonen et un professeur invité, Harold Stone .
Parmi les innovations x86 (plus précisément i8087), on peut citer :
Une représentation en virgule flottante précisément spécifiée au niveau de la chaîne de bits, afin que tous les ordinateurs compatibles interprètent les séquences de bits de la même manière. Ceci permet de transférer avec précision et efficacité des nombres en virgule flottante d'un ordinateur à un autre (après prise en compte de l' endianness ).
Un comportement précisément défini pour les opérations arithmétiques : le résultat doit être produit comme si une arithmétique d’une précision infinie était utilisée pour obtenir une valeur ensuite arrondie selon des règles spécifiques. Ainsi, un programme informatique conforme produira toujours le même résultat pour une entrée donnée, dissipant la réputation quasi mystique que le calcul en virgule flottante s’était forgée en raison de son comportement jusque-là perçu comme non déterministe.
La capacité des conditions exceptionnelles (dépassement de capacité, division par zéro , etc.) à se propager de manière bénigne à travers un calcul, puis à être gérées de façon contrôlée par le logiciel.
Ces caractéristiques seraient intégrées à la norme IEEE 754-1985 (à l'exception de l'encodage des valeurs spéciales et des exceptions). Cependant, la précision interne étendue de l'architecture x87 implique un arrondi explicite des résultats exacts à la précision cible afin de correspondre aux résultats standard de la norme IEEE 754. Néanmoins, le comportement obtenu peut différer d'un arrondi au format cible en raison d'une plage d'exposants potentiellement plus large pour le format étendu.
Plage de nombres à virgule flottante
Un nombre à virgule flottante est composé de deux composantes à virgule fixe , dont la plage de valeurs dépend exclusivement du nombre de bits ou de chiffres utilisés pour sa représentation. Alors que les composantes dépendent linéairement de leur plage de valeurs, la plage de valeurs d'un nombre à virgule flottante dépend linéairement de la plage de sa mantisse et exponentiellement de celle de son exposant, ce qui lui confère une plage de valeurs considérablement plus étendue.
Sur un système informatique typique, un nombre binaire à virgule flottante double précision (64 bits) possède un coefficient de 53 bits (dont 1 bit implicite), un exposant de 11 bits et 1 bit de signe. Puisque 2 <sup>10</sup> = 1024, la plage complète des nombres à virgule flottante positifs normaux dans ce format va de 2 <sup>-1022</sup> ≈ 2 × 10 <sup>-308</sup> à environ 2 <sup>1024</sup> ≈ 2 × 10 <sup> 308</sup> .
Le nombre de nombres à virgule flottante normaux dans un système ( B , P , L , U ) où
B est la base du système,
P est la précision de la mantisse (en base B ),
L est le plus petit exposant du système,
U est le plus grand exposant du système,
est , ou en considérant la valeur 0.
Il existe un plus petit nombre à virgule flottante normal positif,
Niveau de sous-déversement = UFL = ,
qui a un 1 comme premier chiffre et des 0 pour les chiffres restants de la mantisse, et la plus petite valeur possible pour l'exposant.
Il existe un plus grand nombre à virgule flottante,
Niveau de débordement = OFL = ,
qui a B − 1 comme valeur pour chaque chiffre de la mantisse et la plus grande valeur possible pour l'exposant.
IEEE 754 : nombres à virgule flottante dans les ordinateurs modernesIEEE a normalisé la représentation informatique des nombres binaires à virgule flottante dans la norme IEEE 754 (également connue sous le nom de CEI 60559) en 1985. Cette première norme est respectée par la quasi-totalité des machines modernes. Elle a été révisée en 2008. Les ordinateurs centraux IBM prennent en charge le format hexadécimal à virgule flottante propriétaire d'IBM et le format décimal à virgule flottante IEEE 754-2008 , en plus du format binaire IEEE 754. La série Cray T90 disposait d'une version IEEE, mais le SV1 utilise toujours le format à virgule flottante Cray.La simple précision (binary32) est généralement utilisée pour représenter le type « float » dans la famille de langages C. Il s'agit d'un format binaire occupant 32 bits (4 octets) et dont la mantisse a une précision de 24 bits (environ 7 chiffres décimaux).
La double précision (binary64) est généralement utilisée pour représenter le type « double » dans la famille de langages C. Il s'agit d'un format binaire occupant 64 bits (8 octets) et dont la mantisse a une précision de 53 bits (environ 16 chiffres décimaux).
Le format double étendu , également appelé de manière ambiguë « précision étendue », est un format binaire occupant au moins 79 bits (80 si la règle des bits cachés/implicites n'est pas utilisée) et dont la mantisse a une précision d'au moins 64 bits (environ 19 chiffres décimaux). Les normes C99 et C11 de la famille de langages C, dans leur annexe F (« arithmétique à virgule flottante IEC 60559 »), recommandent l'utilisation du type « long double » pour ce format étendu. L'architecture x86 fournit un format répondant aux exigences minimales (précision de la mantisse de 64 bits, exposant de 15 bits, soit 80 bits au total) . Sur ces processeurs, ce format peut souvent être utilisé avec « long double », bien que la précision étendue ne soit pas disponible avec MSVC. Pour des raisons d'alignement , de nombreux outils stockent cette valeur de 80 bits dans un espace mémoire de 96 ou 128 bits. Sur d'autres processeurs, « long double » peut désigner un format plus grand, tel que la quadruple précision, ou simplement la double précision, si aucune forme de précision étendue n'est disponible.
L’augmentation de la précision de la représentation en virgule flottante réduit généralement la quantité d’ erreurs d’arrondi cumulées dues aux calculs intermédiaires. Parmi les autres formats IEEE, on peut citer :
Précision quadruple (binaire128). Il s'agit d'un format binaire occupant 128 bits (16 octets) et dont la mantisse a une précision de 113 bits (environ 34 chiffres décimaux).
La demi-précision , également appelée binaire16, est une valeur à virgule flottante de 16 bits. Elle est utilisée dans le langage graphique NVIDIA Cg et dans la norme openEXR (où elle est antérieure à son introduction dans la norme IEEE 754).
Tout entier dont la valeur absolue est inférieure à 2<sup> 24</sup> peut être représenté exactement en simple précision, et tout entier dont la valeur absolue est inférieure à 2<sup> 53</sup> peut être représenté exactement en double précision. De plus, une large gamme de puissances de 2 de ce nombre peut être représentée. Ces propriétés sont parfois utilisées pour des données purement entières, afin d'obtenir des entiers 53 bits sur des plateformes prenant en charge les nombres à virgule flottante double précision, mais uniquement les entiers 32 bits.
La norme spécifie certaines valeurs spéciales et leur représentation : l'infini positif ( zéro négatif (−0) distinct du zéro ordinaire (« positif ») et les valeurs « non numériques » ( NaN ).
La comparaison des nombres à virgule flottante, telle que définie par la norme IEEE, diffère légèrement de la comparaison d'entiers classique. Les zéros négatifs et positifs sont considérés comme égaux, et chaque NaN est considéré comme différent de toute valeur, y compris de lui-même. Tous les nombres à virgule flottante finis sont strictement inférieurs à IEEE 754 (basique et étendu) disposant d'implémentations matérielles, la répartition est la suivante :
Bien que l'exposant puisse être positif ou négatif, en binaire, il est stocké comme un nombre non signé auquel est ajouté un biais fixe. Les valeurs nulles dans ce champ sont réservées aux zéros et aux nombres sous-normaux ; les valeurs égales à un sont réservées aux infinis et aux valeurs NaN. L'intervalle de l'exposant pour les nombres normaux est [−126, 127] en simple précision, [−1022, 1023] en double précision et [−16382, 16383] en quadruple précision. Les nombres normaux excluent les valeurs sous-normales, les zéros, les infinis et les valeurs NaN.
Dans les formats d'échange binaire IEEE, le bit de poids fort de la mantisse normalisée n'est pas stocké dans la donnée informatique, car il vaut toujours 1. On l'appelle bit « caché » ou « implicite ». De ce fait, le format simple précision possède une mantisse de 24 bits de précision, le format double précision de 53 bits, le format quadruple précision de 113 bits et le format octuple précision de 237 bits.
Par exemple, il a été démontré ci-dessus que π, arrondi à 24 bits de précision, a :
signe = 0 ; e = 1 ; s = 110010010000111111011011 (bit caché inclus)
La somme du biais de l'exposant (127) et de l'exposant (1) est égale à 128 ; ceci est donc représenté en simple précision comme suit :
0 10000000 10010010000111111011011 (à l'exclusion du bit caché) = 40490FDB sous forme de nombre hexadécimal .
Outre les formats standard IEEE 754 largement utilisés , d'autres formats à virgule flottante sont utilisés, ou ont été utilisés, dans certains domaines spécifiques.
Le format binaire Microsoft (MBF) a été développé pour les produits du langage Microsoft BASIC, notamment le tout premier produit Microsoft, l' Altair BASIC (1975), TRS-80 LEVEL II , MBASIC de CP/M , BASICA d' IBM PC 5150 , GW-BASIC de MS-DOS et QuickBASIC (avant la version 4.00). Les versions 4.00 et 4.50 de QuickBASIC sont passées au format IEEE 754-1985, mais il est possible de revenir au format MBF grâce à l'option de commande /MBF. Le MBF a été conçu et développé sur un processeur Intel 8080 simulé par Monte Davidoff , un camarade de chambre de Bill Gates , au printemps 1975 pour le MITS Altair 8800. La première version, sortie en juillet 1975, prenait en charge un format simple précision (32 bits) en raison du coût de la mémoire de 4 kilo-octets du MITS Altair 8800 . En décembre 1975, la version 8 kilo-octets a ajouté un format double précision (64 bits). Une variante de format simple précision (40 bits) a été adoptée pour d'autres processeurs, notamment le MOS 6502 ( Apple II , Commodore PET , Atari ), le Motorola 6800 (MITS Altair 680) et le Motorola 6809 ( TRS-80 Color Computer ). Tous les produits Microsoft utilisant le langage de 1975 à 1987 ont utilisé le format binaire Microsoft (MBF) jusqu'à ce que Microsoft adopte le format standard IEEE 754 dans tous ses produits à partir de 1988 et jusqu'à leurs versions actuelles. Le MBF comprend le format simple précision (32 bits, « BASIC à 6 chiffres »), le format précision étendue (40 bits, « BASIC à 9 chiffres »), et le format double précision (64 bits). chacun d'eux est représenté avec un exposant de 8 bits, suivi d'un bit de signe, suivi d'une mantisse de respectivement 23, 31 et 55 bits.
Le format bfloat16 requiert la même quantité de mémoire (16 bits) que le format demi-précision IEEE 754 , mais alloue 8 bits à l'exposant au lieu de 5, offrant ainsi la même plage de valeurs qu'un nombre IEEE 754 en simple précision . En contrepartie, la précision est réduite, le champ de la mantisse passant de 10 à 7 bits. Ce format est principalement utilisé pour l'entraînement des modèles d'apprentissage automatique , où la plage de valeurs est plus importante que la précision. De nombreux accélérateurs d'apprentissage automatique prennent en charge ce format.
Le format TensorFloat-32 combine les 8 bits de l'exposant du bfloat16 avec les 10 bits du champ de mantisse de fin des formats demi-précision, ce qui donne une taille de 19 bits. Ce format a été introduit par Nvidia , qui le prend en charge matériellement dans les cœurs Tensor de ses GPU basés sur l'architecture Nvidia Ampere. Son principal inconvénient réside dans sa taille, qui n'est pas une puissance de 2. Cependant, selon Nvidia, ce format ne devrait être utilisé qu'en interne par le matériel pour accélérer les calculs, tandis que les entrées et sorties devraient être stockées au format IEEE 754 32 bits en simple précision.
Les GPU d'architecture Hopper et CDNA 3 offrent deux formats FP8 : l'un avec la même plage numérique que la demi-précision (E5M2) et l'autre avec une précision plus élevée, mais une plage plus réduite (E4M3).
L' architecture GPU Blackwell et CDNA 4 prend en charge les formats FP6 (E3M2 et E2M3) et FP4 (E2M1). Le format FP4 est le plus petit format à virgule flottante compatible avec tous les principes de la norme IEEE 754 (voir minifloat ).
Comparaison des formats à virgule flottante courants
Nombres représentables, conversion et arrondides nombres rationnels dont le développement est fini dans la base correspondante (par exemple, un développement décimal fini en base 10 ou un développement binaire fini en base 2). Les nombres irrationnels, tels que π ou √3, ou les nombres rationnels non finis, doivent être approchés. Le nombre de chiffres (ou de bits) de précision limite également l'ensemble des nombres rationnels pouvant être représentés exactement. Par exemple, le nombre décimal 123456789 ne peut être représenté exactement si seulement huit chiffres décimaux de précision sont disponibles (il serait arrondi à l'une des deux valeurs possibles, soit 12345678 × 10¹ ou 12345679 × 10¹ ) . Il en va de même pour les chiffres non finis ( π , représenté en binaire comme une séquence infinie de bits, est
lorsqu'il est approximé par arrondi à une précision de 24 bits.
En binaire à virgule flottante simple précision, cela est représenté par s = 1,10010010000111111011011 avec e = 1. Cela a une valeur décimale de
3.141592 7410125732421875,
alors qu'une approximation plus précise de la vraie valeur de π est
3,14159265358979323846264338327950 ...
Le résultat de l'arrondi diffère de la valeur exacte d'environ 0,03 partie par million et correspond à la représentation décimale de π sur les sept premières décimales. Cette différence est due à l' erreur de discrétisation et est limitée par l' erreur machine (epsilon) .
La différence arithmétique entre deux nombres à virgule flottante consécutifs représentables ayant le même exposant est appelée unité de dernier rang (ULP). Par exemple, s'il n'existe aucun nombre représentable entre les nombres 1,45A70C22 16 et 1,45A70C24 16 , l'ULP est de 2 × 16 − 8 , soit 2 − 31. Pour les nombres dont l'exposant en base 2 est égal à 0 (c'est-à-dire les nombres dont la valeur absolue est supérieure ou égale à 1 et inférieure à 2), l'ULP est exactement de 2 − 23 , soit environ 10 − 7 en simple précision, et exactement de 2 − 53 , soit environ 10 − 16 en double précision. Le comportement requis pour le matériel conforme à la norme IEEE est que le résultat soit inférieur à la moitié de l'ULP.
Modes d'arrondi
L'arrondi est utilisé lorsque le résultat exact d'une opération en virgule flottante (ou d'une conversion en format virgule flottante) nécessiterait plus de chiffres que la mantisse n'en comporte. La norme IEEE 754 exige un arrondi correct : le résultat arrondi doit être identique à celui obtenu par un calcul arithmétique d'une précision infinie, suivi d'un arrondi (bien qu'en pratique, seuls trois bits supplémentaires soient nécessaires). Il existe plusieurs méthodes d' arrondi . Historiquement, la troncature était la méthode la plus courante. Depuis l'introduction de la norme IEEE 754, la méthode par défaut ( arrondi au plus proche, avec un nombre pair en cas d'égalité , parfois appelée arrondi bancaire) est plus fréquemment utilisée. Cette méthode arrondit le résultat idéal (d'une précision infinie) d'une opération arithmétique à la valeur représentable la plus proche et fournit cette représentation comme résultat. En cas d'égalité, on choisit la valeur qui permet d'obtenir un nombre pair de chiffres après la mantisse. La norme IEEE 754 exige que le même arrondi soit appliqué à toutes les opérations algébriques fondamentales, y compris les racines carrées et les conversions, lorsqu'un résultat numérique (autre que NaN) est produit. Cela signifie que les résultats des opérations IEEE 754 sont entièrement déterminés par tous les bits du résultat, à l'exception de la représentation des valeurs NaN. (Les fonctions de bibliothèque telles que le cosinus et le logarithme ne sont pas obligatoires.)
D'autres options d'arrondi sont également disponibles. La norme IEEE 754 spécifie les modes d'arrondi suivants :
arrondir au plus proche, en cas d'égalité, arrondir au chiffre pair le plus proche à la position requise (mode par défaut et de loin le plus courant).
arrondir au plus proche, en cas d'égalité, arrondir à l'opposé de zéro (optionnel pour les nombres à virgule flottante binaires et couramment utilisé en décimal).
arrondir à l'entier supérieur (vers +∞ ; les résultats négatifs sont donc arrondis vers zéro)
arrondir à l'inférieur (vers −∞ ; les résultats négatifs sont donc arrondis à l'opposé de zéro)
arrondir vers zéro (troncature ; c'est similaire au comportement courant des conversions de nombres flottants en entiers, qui convertissent −3,9 en −3 et 3,9 en 3)
Les modes alternatifs sont utiles lorsque l'erreur introduite doit être limitée. Les applications nécessitant une erreur limitée sont le calcul en virgule flottante multiprécision et l'arithmétique d'intervalles . Les modes d'arrondi alternatifs sont également utiles pour diagnostiquer l'instabilité numérique : si les résultats d'une sous-routine varient sensiblement entre l'arrondi à +∞ et à −∞, il est probable que la sous-routine soit numériquement instable et affectée par une erreur d'arrondi.
Conversion binaire-décimal avec un nombre minimal de chiffres
La conversion d'un nombre binaire à virgule flottante double précision en une chaîne décimale est une opération courante, mais aucun algorithme produisant des résultats à la fois précis et minimaux n'a été publié avant 1990, avec Dragon4 de Steele et White. Parmi les améliorations apportées depuis, on peut citer :
dtoa.c de David M. Gay , une implémentation open-source pratique de nombreuses idées de Dragon4.
Grisu3 offre un gain de vitesse de 4 × grâce à la suppression de l'utilisation de grands nombres . Il doit être utilisé avec une solution de repli, car il échoue dans environ 0,5 % des cas.
Errol3 est un algorithme qui réussit toujours, similaire à Grisu3, mais plus lent. Il n'est apparemment pas aussi performant qu'un Grisu à terminaison anticipée avec repli.
Ryū, un algorithme toujours réussi qui est plus rapide et plus simple que Grisu3.
Schubfach, un algorithme toujours performant basé sur une idée similaire à celle de Ryū, a été développé presque simultanément et indépendamment. Il surpasse Ryū et Grisu3 dans certains benchmarks.
De nombreux environnements d'exécution de langages modernes utilisent Grisu3 avec une solution de repli Dragon4.
Conversion décimal-binaire
Le problème de l'analyse syntaxique d'une chaîne décimale en une représentation binaire à virgule flottante est complexe, et un analyseur syntaxique précis n'est apparu qu'avec les travaux de Clinger en 1990 (implémentés dans dtoa.c). Des travaux ultérieurs ont également progressé dans le sens d'une analyse syntaxique plus rapide.
Opérations en virgule flottante
Pour plus de clarté et de simplicité, les exemples utiliseront une base décimale à 7 chiffres significatifs, conformément à la norme IEEE 754 (decimal32 ). Les principes fondamentaux restent inchangés quelle que soit la base ou la précision, à ceci près que la normalisation est facultative (elle n'affecte pas la valeur numérique du résultat). Dans ce texte, s désigne la mantisse et e l'exposant.
Addition et soustraction
Une méthode simple pour additionner des nombres à virgule flottante consiste à les représenter avec le même exposant. Dans l'exemple ci-dessous, le deuxième nombre (avec l'exposant le plus petit) est décalé de trois chiffres vers la droite, puis on procède à l'addition de manière classique :
Voici le résultat exact, la somme précise des opérandes. Il sera arrondi à sept chiffres après la virgule, puis normalisé si nécessaire. Le résultat final est :
e = 5 ; s=1,235585 (somme finale : 123558,5)
Les trois chiffres de poids faible du deuxième opérande (654) sont perdus. Il s'agit d' une erreur d'arrondi . Dans des cas extrêmes, la somme de deux nombres non nuls peut être égale à l'un d'eux.
Dans les exemples conceptuels précédents, il semblerait qu'un grand nombre de chiffres supplémentaires soient nécessaires à l'additionneur pour garantir un arrondi correct ; cependant, pour l'addition ou la soustraction binaire, avec des techniques d'implémentation soignées, seuls un bit de garde , un bit d'arrondi et un bit de maintien supplémentaire sont nécessaires au-delà de la précision des opérandes.
Un autre problème de perte de signification survient lorsqu'on soustrait des approximations de deux nombres presque égaux. Dans l'exemple suivant, e = 5 ; s = 1,234571 et e = 5 ; s = 1,234567 sont des approximations des nombres rationnels 123457,1467 et 123456,659.
La différence en virgule flottante est calculée avec exactitude car les nombres sont proches — le lemme de Sterbenz le garantit, même en cas de dépassement de capacité négatif lorsque le dépassement progressif est pris en charge. Malgré cela, la différence des nombres originaux est e = −1 ; s = 4,877000, ce qui diffère de plus de 20 % de la différence e = −1 ; s = 4,000000 des approximations. Dans des cas extrêmes, tous les chiffres significatifs de la précision peuvent être perdus. Cette annulation illustre le danger de supposer que tous les chiffres d’un résultat calculé sont significatifs. Le traitement des conséquences de ces erreurs est un sujet d’ analyse numérique ; voir aussi Problèmes de précision .
Multiplication et division
Pour multiplier, on multiplie les mantisses tout en additionnant les exposants, puis on arrondit et on normalise le résultat.
De même, la division s'effectue en soustrayant l'exposant du diviseur de l'exposant du dividende, puis en divisant la mantisse du dividende par la mantisse du diviseur.
Il n'existe pas de problèmes d'annulation ou d'absorption lors de la multiplication ou de la division, bien que de petites erreurs puissent s'accumuler lors d'opérations successives. En pratique, la mise en œuvre de ces opérations en logique numérique peut être assez complexe (voir l'algorithme de multiplication de Booth et l'algorithme de division ).
Syntaxe littérale
Les littéraux pour les nombres à virgule flottante dépendent des langages. On utilise généralement `s` eou ` Es` pour désigner la notation scientifique . Le langage C et la norme IEEE 754 définissent également une syntaxe littérale hexadécimale avec un exposant de base 2 au lieu de 10. Dans des langages comme le C , lorsque l'exposant décimal est omis, une virgule est nécessaire pour les différencier des entiers. D'autres langages ne possèdent pas de type entier (comme JavaScript ) ou n'autorisent pas la surcharge des types numériques (comme Haskell ). Dans ces cas, des chaînes de chiffres telles que ` 123float10 ...
Voici quelques exemples de littéraux à virgule flottante :
99.9
-5000.12
6.02e23
-3e-45
0x1.fffffep+127en C et IEEE 754
Gestion des cas exceptionnelsla division par zéro .
Une opération peut être légale en principe, mais non prise en charge par le format spécifique, par exemple, le calcul de la racine carrée de −1 ou de l’arcsinus de 2 (qui donnent tous deux des nombres complexes ).
Une opération peut être légale en principe, mais son résultat peut être impossible à représenter au format spécifié, car l'exposant est trop grand ou trop petit pour être encodé dans le champ d'exposant. On parle alors de dépassement de capacité (exposant trop grand), de sous-dépassement de capacité (exposant trop petit) ou de dénormalisation (perte de précision).
Avant la norme IEEE, de telles conditions entraînaient généralement l'arrêt du programme ou déclenchaient une exception que le programmeur pouvait intercepter. Le fonctionnement de ce mécanisme dépendant du système, les programmes à virgule flottante n'étaient pas portables .
Le terme « exception », tel qu'il est utilisé dans la norme IEEE 754, désigne une condition exceptionnelle, qui n'est pas nécessairement une erreur. Son usage diffère de celui généralement employé dans des langages de programmation comme C++ ou Java, où une « exception » correspond à un flux d'exécution alternatif, plus proche de ce que la norme IEEE 754 appelle un « piège ». Toutefois, dans ces langages, une exception de flux d'exécution ArithmeticExceptionpeut toujours être levée.
Ce document décrit la méthode par défaut de gestion des exceptions, conformément à la norme IEEE 754 (le mécanisme d'interception optionnel IEEE 754 et les autres modes de gestion des exceptions alternatifs ne sont pas abordés). Les exceptions arithmétiques doivent, par défaut, être enregistrées dans des bits d'état « persistants ». Ces bits ne sont pas réinitialisés par l'opération arithmétique suivante, mais restent activés jusqu'à leur réinitialisation explicite. L'utilisation de ces indicateurs « persistants » permet ainsi de différer le test des conditions exceptionnelles jusqu'à la fin d'une expression ou d'une sous-routine à virgule flottante : sans eux, les conditions exceptionnelles qui ne pourraient être ignorées autrement nécessiteraient un test explicite immédiatement après chaque opération à virgule flottante. Par défaut, une opération renvoie toujours un résultat conforme à sa spécification, sans interrompre le calcul. Par exemple, 1/0 renvoie +∞, tout en activant le bit d'indicateur de division par zéro (cette valeur par défaut de ∞ est conçue pour souvent renvoyer un résultat fini lors d'opérations ultérieures et peut donc être ignorée sans risque).
La norme IEEE 754 d'origine ne prévoyait pas d'opérations pour gérer ces ensembles de bits d'indicateurs d'exceptions arithmétiques. Par conséquent, bien que ces bits aient été implémentés matériellement, les langages de programmation ne permettaient généralement pas d'y accéder (à l'exception de l'assembleur). Au fil du temps, certaines normes de langages de programmation (par exemple, C99 /C11 et Fortran) ont été mises à jour afin de spécifier des méthodes d'accès et de modification des bits d'indicateurs d'état. La version 2008 de la norme IEEE 754 spécifie désormais plusieurs opérations pour accéder aux bits d'indicateurs arithmétiques et les manipuler. Le modèle de programmation étant basé sur un seul thread d'exécution, leur utilisation par plusieurs threads doit être gérée en dehors de la norme (par exemple, C11 spécifie que les indicateurs disposent d' un stockage local au thread ).
La norme IEEE 754 spécifie cinq exceptions arithmétiques qui doivent être enregistrées dans les indicateurs d'état (« bits collants ») :
inexact , défini si la valeur arrondie (et renvoyée) est différente du résultat mathématiquement exact de l'opération.
sous-dépassement , défini si la valeur arrondie est minuscule (comme spécifié dans IEEE 754) et inexacte (ou peut-être limitée si elle présente une perte de dénormalisation, conformément à la version 1985 de IEEE 754), renvoyant une valeur sous-normale incluant les zéros.
L'exception overflow est levée si la valeur absolue de la valeur arrondie est trop grande pour être représentée. Elle renvoie l'infini ou une valeur finie maximale, selon l'arrondi utilisé.
diviser par zéro , définir si le résultat est infini étant donné des opérandes finis, renvoyant une infinité, soit +∞ soit −∞.
invalide , défini si un résultat fini ou infini ne peut pas être renvoyé, par exemple sqrt(−1) ou 0/0, renvoyant un NaN silencieux.
Fig. 1 : résistances en parallèle, avec résistance totale
La valeur de retour par défaut de chaque exception est conçue pour donner le résultat correct dans la majorité des cas, permettant ainsi d'ignorer ces exceptions dans la plupart des codes. L'exception `inexact` renvoie un résultat correctement arrondi, et l'exception `underflow` renvoie une valeur inférieure ou égale au plus petit nombre entier positif normal et peut presque toujours être ignorée. L'exception `divide-by-zero` renvoie l'infini, qui divisera généralement un nombre fini et donnera donc zéro, ou bien une exception invalide ultérieurement dans le cas contraire, et peut donc également être généralement ignorée. Par exemple, la résistance effective de n résistances en parallèle (voir fig. 1) est donnée par ` R<sub>eff </sub> = 0`. Si un court-circuit se produit avec `R<sub>eff </sub> = 0`, `R<sub>eff</sub> = 0` renverra `+∞`, ce qui donnera une résistance finale de 0, comme prévu (voir l'exemple de fraction continue de la norme IEEE 754 pour un autre exemple).
Les exceptions de dépassement et d'invalidité ne peuvent généralement pas être ignorées, mais ne représentent pas nécessairement des erreurs : par exemple, une routine de recherche de racine , dans le cadre de son fonctionnement normal, peut évaluer une fonction transmise à des valeurs en dehors de son domaine, renvoyant NaN et un indicateur d'exception d' invalidité à ignorer jusqu'à ce qu'un point de départ utile soit trouvé.
Problèmes de précision
Le fait que les nombres à virgule flottante ne puissent pas représenter avec exactitude tous les nombres réels, et que les opérations à virgule flottante ne puissent pas représenter avec exactitude les véritables opérations arithmétiques, engendre de nombreuses situations surprenantes. Ceci est lié à la précision limitée avec laquelle les ordinateurs représentent généralement les nombres.
Par exemple, les nombres décimaux 0,1 et 0,01 ne peuvent pas être représentés exactement sous forme de nombres binaires à virgule flottante. Dans le format binaire IEEE 754 (binary32) avec sa mantisse de 24 bits, le résultat de la tentative d'élever au carré l'approximation de 0,1 n'est ni 0,01, ni le nombre représentable le plus proche. Le nombre décimal 0,1 est représenté en binaire par commutatives ( associatives . Autrement dit, distributives . Autrement dit, Annulation : la soustraction d'opérandes presque égaux peut entraîner une perte de précision considérable. Lorsqu'on soustrait deux nombres presque égaux, on annule les chiffres les plus significatifs, ne conservant ainsi que les chiffres insignifiants, et donc les plus sujets à erreur. Par exemple, pour calculer la dérivée d'une fonction, on utilise la formule suivante : Intuitivement, on souhaiterait un h très proche de zéro ; cependant, lors d'opérations en virgule flottante, la plus petite valeur possible ne fournit pas la meilleure approximation de la dérivée. Plus h diminue, plus la différence entre f ( a + h ) et f ( a ) diminue, annulant les chiffres les plus significatifs et les moins sujets à erreur et accentuant l'importance des chiffres les plus sujets à erreur. Par conséquent, la plus petite valeur possible de h donnera une approximation de la dérivée plus erronée qu'une valeur légèrement supérieure. Il s'agit peut-être du problème de précision le plus courant et le plus grave.
Les conversions en entiers ne sont pas intuitives : convertir (63,0/9,0) donne 7, mais convertir (0,63/0,09) peut donner 6. Cela s’explique par le fait que les conversions tronquent généralement les nombres au lieu de les arrondir. Les fonctions plancher et plafond peuvent produire des résultats qui diffèrent d’une unité de la valeur attendue.
Plage d'exposants limitée : les résultats peuvent dépasser la capacité maximale et donner l'infini, ou être inférieurs à la capacité maximale et donner un nombre inférieur à la normale ou zéro. Dans ces cas, la précision sera perdue.
Tester la sécurité d'une division est problématique : vérifier que le diviseur n'est pas nul ne garantit pas qu'une division ne provoquera pas de dépassement de capacité.
Tester l’égalité est problématique. Deux séquences de calcul mathématiquement égales peuvent très bien produire des valeurs à virgule flottante différentes.
Incidents
Le 25 février 1991, une défaillance d' une batterie de missiles MIM-104 Patriot l'empêcha d'intercepter un missile Scud à Dhahran , en Arabie saoudite , contribuant à la mort de 28 soldats du 14e détachement de quartier-maître de l'armée américaine . L'ordinateur de contrôle des armes calculait le temps en dixièmes de seconde depuis le démarrage. Pour la conversion en secondes (nombre à virgule flottante) lors des calculs de vitesse et de position, le logiciel multipliait initialement ce nombre par une approximation binaire à virgule fixe de 24 bits , soit 0,1. Certaines parties du logiciel furent ultérieurement adaptées pour utiliser une conversion plus précise en virgule flottante, mais d'autres ne furent pas mises à jour et continuèrent d'utiliser l'approximation à 24 bits. Ces parties du logiciel présentaient une dérive d'environ 3,43 millisecondes par heure. Après 20 heures, un écart d'environ 68,7 ms a suffi au système de poursuite radar pour perdre la trace des missiles Scud ; le système de contrôle de la batterie de missiles de Dhahran fonctionnait depuis environ 100 heures lorsqu'il n'a pas réussi à suivre et intercepter un missile Scud entrant. L'échec de l'interception n'était pas dû à l'utilisation de nombres à virgule flottante en soi, mais à la soustraction de deux approximations différentes de la conversion d'unités, avec des erreurs différentes lors de la représentation du temps. Ainsi, l'erreur de conversion d'unités dans la différence ne s'annulait pas, mais augmentait indéfiniment avec le temps de fonctionnement.
Le fractionnement en tranches est la pratique consistant à transférer la partie « invisible » d'une transaction dans un compte séparé.
Précision machine et analyse des erreurs rétroactives
La précision machine est une grandeur qui caractérise l'exactitude d'un système à virgule flottante et est utilisée dans l'analyse d'erreur inverse des algorithmes à virgule flottante. Elle est également connue sous le nom d'erreur d'arrondi unitaire ou epsilon machine . Généralement notée
Ceci est important car cela limite l' erreur relative de représentation de tout nombre réel non nul
L'analyse d'erreur rétrograde, dont la théorie a été développée et popularisée par James H. Wilkinson , permet d'établir la stabilité numérique d'un algorithme implémentant une fonction numérique. L'approche fondamentale consiste à démontrer que, malgré l'imprécision du résultat calculé due aux erreurs d'arrondi, celui-ci constitue la solution exacte d'un problème voisin avec des données d'entrée légèrement perturbées. Si la perturbation requise est faible, de l'ordre de l'incertitude des données d'entrée, les résultats sont, en un sens, aussi précis que les données le « méritent ». L'algorithme est alors qualifié de stable rétrograde . La stabilité mesure la sensibilité aux erreurs d'arrondi d'une procédure numérique donnée ; en revanche, le conditionnement d'une fonction pour un problème donné indique sa sensibilité intrinsèque aux petites perturbations de ses données d'entrée et est indépendant de l'implémentation utilisée pour résoudre le problème.
À titre d'exemple trivial, considérons une expression simple donnant le produit scalaire de vecteurs (de longueur deux) et , alors et donc
où
où
Par définition, il s'agit de la somme de deux données d'entrée légèrement perturbées (de l'ordre de Mach E ), et elle est donc stable en arrière. Pour des exemples plus réalistes en algèbre linéaire numérique , voir Higham 2002 et les autres références ci-dessous.
Minimiser l'impact des problèmes de précision
Bien que les opérations arithmétiques individuelles de la norme IEEE 754 soient garanties précises à 0,5 ULP près , les formules plus complexes peuvent présenter des erreurs plus importantes pour diverses raisons. La perte de précision peut être substantielle si un problème ou ses données sont mal conditionnés , c'est-à-dire si le résultat correct est extrêmement sensible à de petites perturbations des données. Cependant, même des fonctions bien conditionnées peuvent subir une perte de précision importante si un algorithme numériquement instable pour ces données est utilisé : des formulations apparemment équivalentes d'expressions dans un langage de programmation peuvent différer sensiblement en termes de stabilité numérique. Une approche permettant d'éliminer le risque d'une telle perte de précision consiste à concevoir et à analyser des algorithmes numériquement stables, ce qui est l'un des objectifs de la branche des mathématiques connue sous le nom d' analyse numérique . Une autre approche permettant de se prémunir contre le risque d'instabilités numériques consiste à calculer des valeurs intermédiaires (valeurs de référence) dans un algorithme avec une précision supérieure à celle requise par le résultat final . Ce calcul peut éliminer, ou réduire considérablement , ce risque : les normes IEEE 754 en quadruple précision et en précision étendue sont conçues à cet effet lors de calculs en double précision
Par exemple, l'algorithme suivant est une implémentation directe pour calculer la fonction , qui est bien conditionnée en . Cependant, on peut montrer qu'elle est numériquement instable et qu'elle perd jusqu'à la moitié des chiffres significatifs portés par l'arithmétique lorsqu'elle est calculée près de 1,0.
compilateur est indispensable. Certaines « optimisations » effectuées par les compilateurs (par exemple, le réordonnancement des opérations) peuvent nuire au bon fonctionnement du logiciel. Les limites des compilateurs et de la conception des langages dans ce domaine font l'objet de controverses : C99 est un exemple de langage où ces optimisations sont spécifiées avec précision afin de garantir la précision numérique. Voir les références externes en bas de cet article.
Une description détaillée des techniques d'écriture de logiciels à virgule flottante de haute qualité dépasse le cadre de cet article ; le lecteur est invité à consulter et les autres références en bas de page. Kahan suggère plusieurs règles empiriques permettant de réduire considérablement, de plusieurs ordres de grandeur , le risque d'anomalies numériques, en complément ou en remplacement d'une analyse numérique plus approfondie. Ces règles incluent : comme indiqué précédemment, le calcul de toutes les expressions et des résultats intermédiaires avec la plus haute précision prise en charge par le matériel (une règle empirique courante consiste à utiliser une précision double de celle du résultat souhaité, c'est-à-dire calculer en double précision pour un résultat final en simple précision, ou en double précision étendue ou quadruple précision pour des résultats allant jusqu'à la double précision ). et en arrondissant les données d'entrée et les résultats à la précision requise et prise en charge par ces données (une précision excessive dans le résultat final, au-delà de celle requise et prise en charge par les données d'entrée, peut induire en erreur, augmenter les coûts de stockage et ralentir les calculs ; de plus, les bits excédentaires peuvent affecter la convergence des procédures numériques : notamment, la première forme de l'exemple itératif présenté ci-dessous converge correctement avec cette règle empirique). D'autres problèmes et techniques sont brièvement décrits ci-après.
Les fractions décimales étant souvent difficiles à représenter exactement en binaire à virgule flottante, ce type d'arithmétique est optimal lorsqu'il sert simplement à mesurer des grandeurs réelles sur une large gamme d'échelles (comme la période orbitale d'une lune autour de Saturne ou la masse d'un proton ), et catastrophique lorsqu'il s'agit de modéliser les interactions de grandeurs exprimées sous forme de chaînes décimales censées être exactes. Les calculs financiers en sont un exemple. C'est pourquoi les logiciels financiers n'utilisent généralement pas de représentation binaire à virgule flottante. Le type de données « decimal » des langages de programmation C# et Python , ainsi que les formats décimaux de la norme IEEE 754-2008 , sont conçus pour éviter les problèmes liés aux représentations binaires à virgule flottante lorsqu'elles sont appliquées à des valeurs décimales exactes saisies par l'utilisateur, et pour garantir un comportement arithmétique conforme aux attentes lors de l'affichage de nombres décimaux.
Les propriétés mathématiques attendues ne se vérifient pas toujours dans le domaine du calcul en virgule flottante. Par exemple, on sait que et que . Cependant, ces propriétés ne sont pas valables lorsque les quantités en jeu résultent de calculs en virgule flottante.
L'utilisation du test d'égalité ( if (x==y) ...) requiert une attention particulière lors de la manipulation de nombres à virgule flottante. Même des expressions simples comme 0.6 / 0.2 - 3 == 0ne seront pas vraies sur la plupart des ordinateurs (en double précision IEEE 754, par exemple, 0.6 / 0.2 - 3est approximativement égal à ).géométrie algorithmique , des tests exacts permettant de déterminer si un point se situe sur ou hors d’une droite ou d’un plan défini par d’autres points peuvent être réalisés à l’aide de méthodes de précision adaptative ou d’arithmétique exacte.
L'addition d'un vecteur de valeurs à virgule flottante est un algorithme fondamental en calcul scientifique ; il est donc essentiel de savoir identifier les situations où une perte de signification peut survenir. Par exemple, lors de l'addition d'un très grand nombre de nombres, les termes de l'addition sont très petits par rapport à la somme. Cela peut entraîner une perte de signification. Une addition typique ressemblerait alors à ceci :
3253.671 + 3,141276 ----------- 3256.812
Les trois derniers chiffres des termes sont effectivement perdus. Supposons, par exemple, que l'on doive additionner de nombreux nombres, tous approximativement égaux à 3. Après avoir additionné 1 000 d'entre eux, la somme cumulée est d'environ 3 000 ; les chiffres perdus ne sont pas retrouvés. L' algorithme de sommation de Kahan peut être utilisé pour réduire les erreurs.
Les erreurs d'arrondi peuvent affecter la convergence et la précision des procédures numériques itératives. Par exemple, Archimède a approché π en calculant les périmètres des polygones inscrits et circonscrits à un cercle, en commençant par des hexagones et en doublant successivement le nombre de côtés. Comme indiqué précédemment, les calculs peuvent être réorganisés de manière à être mathématiquement équivalents mais moins sujets aux erreurs ( analyse numérique ). Deux formes de la formule de récurrence pour le polygone circonscrit sont :
Première forme :
Deuxième forme :
, convergeant comme
Voici un calcul utilisant l'arithmétique « double » IEEE (une mantisse avec une précision de 53 bits) :
i 6 × 2 i × t i , première forme 6 × 2 i × t i , deuxième forme --------------------------------------------------------- 0 précision de plus en plus problématique . L'application répétée de la récurrence améliore d'abord la précision, puis la dégrade. Elle ne dépasse jamais environ 8 chiffres, alors que l'arithmétique 53 bits devrait permettre une précision d'environ 16 chiffres. Avec la seconde forme de la formule de récurrence, la précision converge vers 15 chiffres.
Optimisation « calcul rapide »
Le manque d' associativité des opérations en virgule flottante, mentionné précédemment, signifie que les compilateurs ne peuvent pas réorganiser les expressions arithmétiques aussi efficacement qu'avec l'arithmétique entière et à virgule fixe, ce qui constitue un obstacle aux optimisations telles que l'élimination des sous-expressions communes et l'auto- vectorisation . L'option « calcul rapide » de nombreux compilateurs (ICC, GCC, Clang, MSVC…) active la réassociation, mais repose sur des hypothèses non sécurisées comme l'absence de NaN et de nombres infinis dans la norme IEEE 754. Certains compilateurs offrent également des options plus précises permettant d'activer uniquement la réassociation ou de marquer des régions spécifiques du code pour une optimisation plus poussée. Dans les deux cas, le programmeur est exposé à de nombreux problèmes de précision mentionnés précédemment pour la partie du programme utilisant le calcul rapide.
Dans certains compilateurs (GCC et Clang [lorsqu'une installation de GCC est présente]), l'activation des calculs « rapides » peut entraîner la désactivation des nombres à virgule flottante sous-normaux au démarrage du programme, ce qui affecte le comportement en virgule flottante non seulement du code généré, mais aussi de tout programme utilisant ce code comme bibliothèque . Ce problème a été corrigé dans GCC 13.
Dans la plupart des compilateurs Fortran , conformément à la norme ISO/IEC 1539-1:2004, la réassociation est le comportement par défaut, les erreurs étant largement évitées par l'option « protéger les parenthèses » (également activée par défaut). Cette option empêche le compilateur de réassocier les données au-delà des limites des parenthèses. Le compilateur Intel Fortran constitue une exception notable.
Un problème courant en calcul « rapide » est que les sous-expressions peuvent ne pas être optimisées de manière identique d'un endroit à l'autre, ce qui entraîne des différences inattendues. Une interprétation possible de ce problème est que le calcul « rapide », tel qu'implémenté actuellement, possède une sémantique mal définie. Icing , un compilateur vérifié, propose une tentative de formalisation des optimisations en calcul « rapide ».