270 votes

le plus grand nombre entier qui peut être stocké dans un double

Quel est le plus grand nombre entier "non flottant" qui peut être stocké dans un type double IEEE 754 sans perdre la précision ?

613voto

Steve Jessop Points 166970

Le plus grand nombre entier qui peut être stocké dans un double sans perdre la précision est le même que la plus grande valeur possible d'un double. C'est-à-dire DBL_MAX soit environ 1,8 × 10 308 (si votre double est un double IEEE 754 de 64 bits). C'est un nombre entier. Il est représenté exactement. Que voulez-vous de plus ?

Allez-y, demandez-moi quel est le plus grand nombre entier, tel qu'il et tous les entiers plus petits peuvent être stockés dans des doubles IEEE 64 bits sans perte de précision. Un double IEEE 64-bit a 52 bits de mantisse, donc je pense que c'est 2 53 :

  • 2 53 + 1 ne peut pas être stocké, car le 1 du début et le 1 de la fin ont trop de zéros entre eux.
  • Tout ce qui est inférieur à 2 53 peut être stockée, avec 52 bits explicitement stockés dans la mantisse, puis l'exposant vous en donne un autre.
  • 2 53 peut évidemment être stocké, puisqu'il s'agit d'une petite puissance de 2.

Ou une autre façon de voir les choses : une fois que le biais a été retiré de l'exposant, et en ignorant le bit de signe qui n'est pas pertinent pour la question, la valeur stockée par un double est une puissance de 2, plus un entier de 52 bits multiplié par 2. exposant 52 . Ainsi, avec l'exposant 52, vous pouvez stocker toutes les valeurs de 2 52 jusqu'à 2 53   1. Puis avec l'exposant 53, le prochain nombre que vous pouvez stocker après 2 53 est de 2 53 + 1 × 2 53 52 . La perte de précision se produit donc d'abord avec 2 53 + 1.

159 votes

+1 Bon travail consistant à remarquer que la question ne signifiait pas vraiment ce que l'auteur de la question voulait probablement dire et à fournir les deux réponses ("techniquement correct" et "probablement attendu").

76 votes

Ou "faire des bêtises" et "essayer d'aider" comme j'ai tendance à les appeler :-)

0 votes

J'ai juste ajouté plus de précision dans la description de ma question. Je parlais du plus grand entier "non flottant".

95voto

pmg Points 52636

9007199254740992 (soit 9 007 199 254 740 992 ou 2^53) sans aucune garantie :)

Programme

#include <math.h>
#include <stdio.h>

int main(void) {
  double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
  while (dbl + 1 != dbl) dbl++;
  printf("%.0f\n", dbl - 1);
  printf("%.0f\n", dbl);
  printf("%.0f\n", dbl + 1);
  return 0;
}

Résultat

9007199254740991
9007199254740992
9007199254740992

8 votes

En supposant qu'il sera "proche" mais inférieur à 2^N, un test plus rapide est le suivant double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl); ce qui donne le même résultat

4 votes

@Seph what the... ? Non ? while (dbl == --dbl) tournera en boucle pour toujours ou pas du tout :) (dans ce cas, pas du tout, puisque c'est un 2^N). Vous devrez l'aborder par le bas. Il en résultera effectivement aussi un résultat de moins que le résultat attendu (puisque la seule vérification dans la boucle while décrémente dbl). Et cela dépend de l'ordre d'exécution, si la décrémentation est faite avant ou après l'évaluation du côté gauche (qui est indéfini pour autant que je sache). Si c'est le premier, ce sera toujours vrai et la boucle sera éternelle.

14 votes

Peut-être indiquer que 2^53=9,007,199,254,740,992 quelque part.

29voto

Carl Smotricz Points 36400

Wikipedia dit ceci dans le même contexte avec un lien vers IEEE 754 :

Sur un système informatique classique, un nombre binaire à virgule flottante de "double précision" (64 bits) possède un coefficient de 53 bits (dont un est implicite), un exposant de 11 bits et un bit de signe.

2^53 est un peu plus de 9 * 10^15.

0 votes

@Steve Jessop Plus ou moins, c'est en effet ce que je dis. J'ai aussi rencontré des systèmes matériels qui n'ont pas de FPU et qui doivent quand même être conformes à l'IEEE, donc ce truc de "système typique" ne m'aide pas vraiment si je reviens ici 8 mois plus tard et que j'ai besoin de la même info pour mon microcontrôleur basé sur 68K (en supposant qu'il n'ait pas de FPU... je ne me souviens plus).

16 votes

@San Jacinto - "C'est inutile" est indûment sévère. La réponse est très utile, mais pas autant qu'elle l'aurait été si elle avait inclus le commentaire selon lequel les systèmes informatiques typiques utilisent effectivement la représentation IEEE 754.

0 votes

@Stephen C. Steel, en fait vous avez raison. Dans mon scénario, en y revenant plus tard et en cherchant le maximum de l'IEEE, il est impossible de savoir ce qu'est un "système typique", mais il y a encore du mérite dans la réponse en dehors de cette plainte.

8voto

Dolphin Points 2694

Il faut regarder la taille de la mantisse. Un nombre à virgule flottante IEEE 754 de 64 bits (qui a 52 bits, plus 1 implicite) peut représenter exactement des entiers dont la valeur absolue est inférieure ou égale à 2^53.

8 votes

Il peut aussi représenter exactement 2^53 :-)

4voto

Jay Points 330

2 votes

Cette réponse serait bien meilleure avec une citation.

2 votes

@Carl bien, si l'entier a des zéros au-delà de la gauche, alors il est stocké précisément.

4 votes

@ tous ceux qui ont voté contre : 1.7976931348623157 × 10^308 est un entier exact. Vous avez tous besoin de suivre des cours de rattrapage en maths ou quoi ???

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X