Format à virgule flottante double précision - Double-precision floating-point format

Le format à virgule flottante double précision (parfois appelé FP64 ou float64 ) est un format de nombre informatique , occupant généralement 64 bits dans la mémoire de l'ordinateur ; il représente une large plage dynamique de valeurs numériques en utilisant une virgule de base flottante .

La virgule flottante est utilisée pour représenter des valeurs fractionnaires, ou lorsqu'une plage plus large est nécessaire que celle fournie par la virgule fixe (de la même largeur de bit), même au détriment de la précision. La double précision peut être choisie lorsque la plage ou la précision de la simple précision serait insuffisante.

Dans l' IEEE 754-2008 norme , le format de base 2 64 bits est officiellement appelé binary64 ; il a été appelé double dans IEEE 754-1985 . IEEE 754 spécifie des formats à virgule flottante supplémentaires, y compris des représentations en simple précision 32 bits en base 2 et, plus récemment, des représentations en base 10.

L'un des premiers langages de programmation à fournir des types de données à virgule flottante simple et double précision était Fortran . Avant l'adoption généralisée de l'IEEE 754-1985, la représentation et les propriétés des types de données à virgule flottante dépendaient du fabricant de l' ordinateur et du modèle informatique, ainsi que des décisions prises par les implémenteurs du langage de programmation. Par exemple, le type de données double précision de GW-BASIC était le format à virgule flottante MBF 64 bits .

Format à virgule flottante binaire double précision IEEE 754 : binary64

La virgule flottante binaire double précision est un format couramment utilisé sur les PC, en raison de sa gamme plus large que la virgule flottante simple précision, malgré ses performances et son coût en bande passante. Il est communément appelé simplement double . La norme IEEE 754 spécifie un binaire64 comme ayant :

Le bit de signe détermine le signe du nombre (y compris lorsque ce nombre est zéro, ce qui est signé ).

Le champ exposant est un entier non signé de 11 bits de 0 à 2047, sous forme biaisée : une valeur d'exposant de 1023 représente le zéro réel. Les exposants vont de -1022 à +1023 car les exposants de -1023 (tous des 0) et +1024 (tous des 1) sont réservés aux nombres spéciaux.

La précision de la mantisse de 53 bits donne une précision de 15 à 17 chiffres décimaux significatifs (2 −53  1,11 × 10 −16 ). Si une chaîne décimale avec au plus 15 chiffres significatifs est convertie en représentation double précision IEEE 754, puis reconvertie en chaîne décimale avec le même nombre de chiffres, le résultat final doit correspondre à la chaîne d'origine. Si un nombre IEEE 754 double précision est converti en une chaîne décimale avec au moins 17 chiffres significatifs, puis reconverti en représentation double précision, le résultat final doit correspondre au nombre d'origine.

Le format est écrit avec la mantisse ayant un bit entier implicite de valeur 1 (sauf pour les données spéciales, voir le codage des exposants ci-dessous). Avec les 52 bits de la fraction (F) significande apparaissant dans le format mémoire, la précision totale est donc de 53 bits (environ 16 chiffres décimaux, 53 log 10 (2) 15,955). Les bits sont disposés comme suit :

Format à virgule flottante double IEEE 754.svg

La valeur réelle supposée par une donnée double précision de 64 bits avec un exposant biaisé donné et une fraction de 52 bits est

ou

Entre 2 52 = 4 503 599 627 370 496 et 2 53 = 9 007 199 254 740 992, les nombres représentables sont exactement les entiers. Pour l'intervalle suivant, de 2 53 à 2 54 , tout est multiplié par 2, donc les nombres représentables sont les pairs, etc. Inversement, pour l'intervalle précédent de 2 51 à 2 52 , l'espacement est de 0,5, etc.

L'espacement en fraction des nombres compris entre 2 n et 2 n +1 est de 2 n -52 . L'erreur d'arrondi relative maximale lors de l'arrondi d'un nombre au plus proche représentable (la machine epsilon ) est donc de 2 -53 .

La largeur de 11 bits de l'exposant permet la représentation de nombres entre 10 -308 et 10 308 , avec une précision complète de 15-17 chiffres décimaux. En compromettant la précision, la représentation subnormale permet des valeurs encore plus petites jusqu'à environ 5 × 10 -324 .

Codage de l'exposant

L'exposant à virgule flottante binaire à double précision est codé à l'aide d'une représentation binaire décalée , le décalage de zéro étant de 1023 ; également connu sous le nom de biais d'exposant dans la norme IEEE 754. Des exemples de telles représentations seraient :

e = = =1 : 00000000001200116 (plus petit exposant pour les nombres normaux )
e = = = 1023 : 0111111111123ff16 (décalage zéro)
e = = = 1029 : 10000000101240516
e = = =2046 : 1111111111027fe16 (exposant le plus élevé)

Les exposants et ont une signification particulière : 000167ff16

  • 000000000002= est utilisé pour représenter un zéro signé (si F = 0) et des sous - normes (si F 0); et00016
  • 111111111112= est utilisé pour représenter (si F = 0) et NaNs (si F ≠ 0),7ff16

F est la partie fractionnaire de la mantisse . Tous les modèles de bits sont un codage valide.

À l'exception des exceptions ci-dessus, l'ensemble du nombre en double précision est décrit par :

Dans le cas des sous - normales ( e = 0) le nombre en double précision est décrit par :

Endianité

Bien que les processeurs x86 omniprésents d'aujourd'hui utilisent un stockage little-endian pour tous les types de données (entiers, virgule flottante), il existe un certain nombre d'architectures matérielles où les nombres à virgule flottante sont représentés sous forme big-endian tandis que les entiers sont représentés sous forme de petit-boutiste. forme endian. Il existe des processeurs ARM qui ont une représentation à virgule flottante moitié little-endian, moitié big-endian pour les nombres en double précision : les deux mots de 32 bits sont stockés dans des registres entiers de type little-endian, mais le plus significatif en premier. Parce qu'il y a eu de nombreux formats à virgule flottante sans représentation standard " réseau " pour eux, la norme XDR utilise IEEE 754 big-endian comme représentation. Il peut donc sembler étrange que la norme à virgule flottante IEEE 754 très répandue ne spécifie pas le caractère endian. Théoriquement, cela signifie que même les données à virgule flottante IEEE standard écrites par une machine peuvent ne pas être lisibles par une autre. Cependant, sur les ordinateurs standard modernes (c'est-à-dire implémentant IEEE 754), on peut en pratique supposer en toute sécurité que l'endianité est la même pour les nombres à virgule flottante que pour les entiers, ce qui rend la conversion simple quel que soit le type de données. ( Cependant, les petits systèmes embarqués utilisant des formats à virgule flottante spéciaux peuvent être une autre affaire.)

La virgule flottante VAX stocke les mots 16 bits petit-boutiste dans l'ordre gros-boutiste.

Exemples en double précision

0 01111111111 0000000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1
0 01111111111 0000000000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1.0000000000000002, le plus petit nombre > 1
0 01111111111 000000000000000000000000000000000000000000000000000010 2 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004
0 10000000000 00000000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2
1 10000000000 0000000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2
0 10000000000 10000000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1,1 2 = 11 2 = 3
0 10000000001 00000000000000000000000000000000000000000000000000000000 2 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4
0 10000000001 010000000000000000000000000000000000000000000000000000 2 4014 0000 0000 0000 16 +2 2 × 1,01 2 = 101 2 = 5
0 10000000001 10000000000000000000000000000000000000000000000000000000 2 4018 0000 0000 0000 16 ≙ +2 2 × 1,1 2 = 110 2 = 6
0 100000000011 01110000000000000000000000000000000000000000000000000 2 4037 0000 0000 0000 16 ≙ +2 4 × 1,0111 2 = 10111 2 = 23
0 01111111000 1000000000000000000000000000000000000000000000000000000 2 3F88 0000 0000 0000 16 ≙ +2 −7 × 1,1 2 = 0,00000011 2 = 0,01171875 (3/256)
0 00000000000 000000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (double positif inférieur à la normale)
0 00000000000 1111111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × (1 − 2 −52 ) ≈ 2.2250738585072009 × 10 −308 (Max. double subnormal)
0 00000000001 00000000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2.2250738585072014 × 10 −308 (Min. normal positif double)
0 11111111110 11111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (1 + (1 − 2 −52 )) ≈ 1.7976931348623157 × 10 308 (Max. Double)
0 00000000000 0000000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0
1 00000000000 0000000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0
0 11111111111 0000000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ +∞ (infini positif)
1 11111111111 0000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (infini négatif)
0 11111111111 000000000000000000000000000000000000000000000000000001 2 7FF0 0000 0000 0001 16 ≙ NaN (sNaN sur la plupart des processeurs, tels que x86 et ARM)
0 11111111111 1000000000000000000000000000000000000000000000000000001 2 7FF8 0000 0000 0001 16 ≙ NaN (qNaN sur la plupart des processeurs, tels que x86 et ARM)
0 11111111111 11111111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (un codage alternatif de NaN)
0 01111111101 0101010101010101010101010101010101010101010101010101 2 = 3FD5 5555 5555 5555 16 ≙ +2 −2 × (1 + 2 −2 + 2 −4 + ... + 2 −52 ) ≈ 1 / 3
0 10000000000 1001001000011111101101010100010001000010110100011000 2 = 4009 21FB 5444 2D18 16 pi

Les codages de qNaN et sNaN ne sont pas complètement spécifiés dans IEEE 754 et dépendent du processeur. La plupart des processeurs, tels que la famille x86 et les processeurs de la famille ARM , utilisent le bit le plus significatif du champ significand pour indiquer un NaN silencieux ; c'est ce qui est recommandé par IEEE 754. Les processeurs PA-RISC utilisent le bit pour indiquer une signalisation NaN.

Par défaut, 1 / 3 arrondit à l'inférieur, au lieu d'augmenter comme simple précision , en raison du nombre impair de bits dans la mantisse.

Plus en détail:

Given the hexadecimal representation 3FD5 5555 5555 555516,
  Sign = 0
  Exponent = 3FD16 = 1021
  Exponent Bias = 1023 (constant value; see above)
  Fraction = 5 5555 5555 555516
  Value = 2(Exponent − Exponent Bias) × 1.Fraction – Note that Fraction must not be converted to decimal here
        = 2−2 × (15 5555 5555 555516 × 2−52)
        = 2−54 × 15 5555 5555 555516
        = 0.333333333333333314829616256247390992939472198486328125
        ≈ 1/3

Vitesse d'exécution avec arithmétique double précision

L'utilisation de variables à virgule flottante en double précision et de fonctions mathématiques (par exemple, sin, cos, atan2, log, exp et sqrt) est plus lente que de travailler avec leurs homologues en simple précision. Un domaine de l'informatique où cela pose un problème particulier est le code parallèle s'exécutant sur des GPU. Par exemple, lors de l'utilisation de la plate- forme CUDA de NVIDIA , les calculs en double précision prennent, selon le matériel, environ 2 à 32 fois plus de temps que ceux effectués en simple précision .

Limitations de précision sur les valeurs entières

  • Les entiers de −2 53 à 2 53 (−9.007.199.254.740.992 à 9.007.199.254.740.992) peuvent être exactement représentés
  • Entiers compris entre 2 53 et 2 54 = 18 014 398 509 481 984 arrondis à un multiple de 2 (nombre pair)
  • Entiers entre 2 54 et 2 55 = 36 028 797 018 963 968 arrondis à un multiple de 4

Implémentations

Les doubles sont implémentés dans de nombreux langages de programmation de différentes manières, telles que les suivantes. Sur les processeurs avec uniquement une précision dynamique, tels que x86 sans SSE2 (ou lorsque SSE2 n'est pas utilisé, à des fins de compatibilité) et avec une précision étendue utilisée par défaut, le logiciel peut avoir des difficultés à répondre à certaines exigences.

C et C++

C et C++ offrent une grande variété de types arithmétiques . La double précision n'est pas exigée par les normes (sauf par l'annexe facultative F du C99 , couvrant l'arithmétique IEEE 754), mais sur la plupart des systèmes, le doubletype correspond à la double précision. Cependant, sur x86 32 bits avec une précision étendue par défaut, certains compilateurs peuvent ne pas être conformes à la norme C ou l'arithmétique peut souffrir d'un double arrondi .

Fortran

Fortran fournit plusieurs types entiers et réels, et le type 64 bits real64, accessible via le module intrinsèque de Fortran iso_fortran_env, correspond à la double précision.

Lisp commun

Common Lisp propose les types SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT et LONG-FLOAT. La plupart des implémentations fournissent des SINGLE-FLOAT et DOUBLE-FLOAT avec les autres types de synonymes appropriés. Common Lisp fournit des exceptions pour attraper les débordements et les débordements en virgule flottante, et l'exception en virgule flottante inexacte, selon IEEE 754. Aucun infini et NaN ne sont décrits dans la norme ANSI, cependant, plusieurs implémentations les fournissent en tant qu'extensions.

Java

Sur Java avant la version 1.2, chaque implémentation devait être conforme à IEEE 754. La version 1.2 a permis aux implémentations d'apporter une précision supplémentaire dans les calculs intermédiaires pour des plates-formes comme x87 . Ainsi, un modificateur strictfp a été introduit pour imposer des calculs IEEE 754 stricts. La virgule flottante stricte a été restaurée dans Java 17.

JavaScript

Comme spécifié par la norme ECMAScript , toutes les opérations arithmétiques en JavaScript doivent être effectuées à l'aide d'arithmétique à virgule flottante double précision.

Voir également

  • IEEE 754 , norme IEEE pour l'arithmétique à virgule flottante

Notes et références