web-dev-qa-db-fra.com

Quelle plage de nombres peut être représentée dans un système IEEE-754 à 16, 32 et 64 bits?

Je sais un peu comment les nombres à virgule flottante sont représentés, mais pas assez, je le crains.

La question générale est:

Pour une précision donnée (pour mes besoins, le nombre de décimales précises en base 10), quelle plage de nombres peut être représentée pour les systèmes IEEE-754 16, 32 et 64 bits?

Plus précisément, je ne suis intéressé que par la plage de nombres 16 bits et 32 ​​bits précis à +/- 0,5 (ceux qui sont placés) ou +/- 0,0005 (les millièmes).

70
Nate Parsons

Pour un IEEE-754 nombre à virgule flottante [~ # ~] x [~ # ~] , si

2^E <= abs(X) < 2^(E+1)

puis la distance entre [~ # ~] x [~ # ~] jusqu'au prochain plus grand nombre à virgule flottante représentable ( epsilon ) est:

epsilon = 2^(E-52)    % For a 64-bit float (double precision)
epsilon = 2^(E-23)    % For a 32-bit float (single precision)
epsilon = 2^(E-10)    % For a 16-bit float (half precision)

Les équations ci-dessus nous permettent de calculer les éléments suivants:

  • Pour demi-précision ...

    Si vous souhaitez une précision de +/- 0,5 (ou 2 ^ -1), la taille maximale que le nombre peut être est de 2 ^ 10. Tout plus grand que cela et la distance entre les nombres à virgule flottante est supérieure à 0,5.

    Si vous voulez une précision de +/- 0,0005 (environ 2 ^ -11), la taille maximale que le nombre peut être est 1. Toute plus grande que cela et la distance entre les nombres à virgule flottante est supérieure à 0,0005.

  • Pour simple précision ...

    Si vous souhaitez une précision de +/- 0,5 (ou 2 ^ -1), la taille maximale que le nombre peut être est 2 ^ 23. Tout plus grand que cela et la distance entre les nombres à virgule flottante est supérieure à 0,5.

    Si vous voulez une précision de +/- 0,0005 (environ 2 ^ -11), la taille maximale que le nombre peut être est 2 ^ 13. Tout plus grand que cela et la distance entre les nombres à virgule flottante est supérieure à 0,0005.

  • Pour double précision ...

    Si vous voulez une précision de +/- 0,5 (ou 2 ^ -1), la taille maximale que le nombre peut être est 2 ^ 52. Tout plus grand que cela et la distance entre les nombres à virgule flottante est supérieure à 0,5.

    Si vous voulez une précision de +/- 0,0005 (environ 2 ^ -11), la taille maximale que le nombre peut être est 2 ^ 42. Tout plus grand que cela et la distance entre les nombres à virgule flottante est supérieure à 0,0005.

94
gnovice

Pour les entiers à virgule flottante (je donnerai ma réponse en termes de double précision IEEE), chaque entier compris entre 1 et 2 ^ 53 est exactement représentable. Au-delà de 2 ^ 53, les entiers qui sont exactement représentables sont espacés par des puissances croissantes de deux. Par exemple:

  • Chaque 2ème entier compris entre 2 ^ 53 + 2 et 2 ^ 54 peut être représenté exactement.
  • Chaque 4ème entier entre 2 ^ 54 + 4 et 2 ^ 55 peut être représenté exactement.
  • Chaque 8ème entier entre 2 ^ 55 + 8 et 2 ^ 56 peut être représenté exactement.
  • Chaque 16ème entier entre 2 ^ 56 + 16 et 2 ^ 57 peut être représenté exactement.
  • Chaque 32ème entier entre 2 ^ 57 + 32 et 2 ^ 58 peut être représenté exactement.
  • Chaque 64ème entier entre 2 ^ 58 + 64 et 2 ^ 59 peut être représenté exactement.
  • Chaque 128e entier compris entre 2 ^ 59 + 128 et 2 ^ 60 peut être représenté exactement.
  • Chaque 256ème entier entre 2 ^ 60 + 256 et 2 ^ 61 peut être représenté exactement.
  • Chaque 512e entier compris entre 2 ^ 61 + 512 et 2 ^ 62 peut être représenté exactement. . . .

Les nombres entiers qui ne sont pas exactement représentables sont arrondis à l'entier représentable le plus proche, de sorte que l'arrondi le plus défavorable correspond à la moitié de l'espacement entre les nombres entiers représentables.

21
Rick Regan

La précision citée du lien de Peter R avec la référence MSDN est probablement une bonne règle de base, mais bien sûr la réalité est plus compliquée.

Le fait que le "point" en "virgule flottante" soit un point binaire et non un point décimal a un moyen de vaincre nos intuitions. L'exemple classique est 0,1, qui nécessite une précision d'un seul chiffre en décimal mais n'est pas du tout représentable exactement en binaire.

Si vous avez un week-end à tuer, jetez un œil à Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante . Vous serez probablement particulièrement intéressé par les sections sur Précision et Conversion binaire en décimal .

17
bendin

Tout d'abord, ni IEEE-754-2008 ni -1985 n'ont de flottants 16 bits; mais c'est un ajout proposé avec un exposant de 5 bits et une fraction de 10 bits. IEE-754 utilise un bit de signe dédié, donc la plage positive et négative est la même. De plus, la fraction a un 1 implicite devant, vous obtenez donc un peu plus.

Si vous voulez une précision à l'endroit où vous pouvez représenter chaque entier, la réponse est assez simple: l'exposant déplace la virgule décimale vers l'extrémité droite de la fraction. Ainsi, une fraction de 10 bits vous donne ± 211.

Si vous voulez un bit après la virgule décimale, vous abandonnez un bit avant, vous avez donc ± 2dix.

La précision simple a une fraction de 23 bits, vous auriez donc ± 224 entiers.

Le nombre de bits de précision dont vous avez besoin après la virgule décimale dépend entièrement des calculs que vous effectuez et du nombre que vous effectuez.

  • 2dix = 1 024
  • 211 = 2 048
  • 223 = 8 388 608
  • 224 = 16 777 216
  • 253 = 9 007 199 254 740 992 (double précision)
  • 2113 = 10,384,593,717,069,655,257,060,992,658,440,192 (quad-précision)

Voir également

4
derobert

Voir IEEE 754-1985 :

v = (-1)^sign * s^(exponent-exponent_bias) * (1 + fraction)

Remarque (1 + fraction). Comme @ bendin le souligne, en utilisant le virgule flottante binaire, vous ne pouvez pas exprimer de valeurs décimales simples telles que 0,1. L'implication est que vous pouvez introduire des erreurs d'arrondi en effectuant plusieurs fois de simples ajouts ou en appelant des choses comme la troncature. Si vous êtes intéressé par une précision quelconque, la seule façon d'y parvenir est d'utiliser une décimale à virgule fixe, qui est essentiellement un entier mis à l'échelle.

2
Eugene Yokota

Il m'a fallu un certain temps pour comprendre que lorsque j'utilisais des doubles en Java, je ne perdais pas une précision significative dans les calculs. la virgule flottante a en fait une très bonne capacité à représenter les nombres avec une précision assez raisonnable. La précision que je perdais était immédiatement lors de la conversion décimal nombres saisis par les utilisateurs binaire représentation en virgule flottante prise en charge en mode natif. J'ai récemment commencé à convertir tous mes numéros en BigDecimal. BigDecimal est beaucoup plus de travail à traiter dans le code que les flottants ou les doubles, car ce n'est pas l'un des types primitifs. Mais d'un autre côté, je serai en mesure de représenter exactement les chiffres que les utilisateurs tapent.

0
PanCrit

Si je comprends bien votre question, cela dépend de votre langue.
Pour C #, consultez la référence MSDN . Float a une précision de 7 chiffres et une précision double de 15-16 chiffres.

0
Peter R