Quel est le plus grand nombre entier “non flottant” pouvant être stocké dans un double type IEEE 754 sans perdre en précision?
Le nombre entier le plus grand / le plus grand pouvant être stocké dans un double sans perte de précision est identique à la plus grande valeur possible d’un double. C’est-à-dire DBL_MAX
ou environ 1,8 × 10 308 (si votre double est un double IEEE 754 64 bits). C’est un entier. C’est représenté exactement. Que veux-tu de plus?
Continuez, demandez-moi quel est le plus grand nombre entier, de sorte que tous les entiers plus petits puissent être stockés dans des doublons IEEE 64 bits sans perdre en précision. Un double IEEE 64 bits a 52 bits de mantisse, donc je pense que c’est 2 53 :
Ou une autre façon de voir les choses: une fois que le biais a été enlevé de l’exposant, et en ignorant le signe comme non pertinent à 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 . Donc, avec l’exposant 52, vous pouvez stocker toutes les valeurs de 2 52 à 2 53 – 1. Puis avec l’exposant 53, le prochain chiffre que vous pouvez stocker après 2 53 est 2 53 + 1 × 2 53 – 52 . La perte de précision se produit donc tout d’abord avec 2 53 + 1.
9007199254740992 (soit 9 007 199 254 740 992) sans garantie 🙂
Programme
#include #include 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
Wikipedia a ceci à dire dans le même contexte avec un lien vers IEEE 754 :
Sur un système informatique classique, un nombre à virgule flottante binary «double précision» (64 bits) a un coefficient de 53 bits (dont un implicite), un exposant de 11 bits et un bit de signe.
2 ^ 53 est juste un peu plus de 9 * 10 ^ 15.
Le plus grand nombre entier pouvant être représenté dans IEEE 754 double (64 bits) est identique à la plus grande valeur que le type peut représenter, puisque cette valeur est elle-même un entier.
Ceci est représenté par 0x7FEFFFFFFFFFFFFF
, qui est composé de:
0x7FE
(2046, qui représente 1023 après le biais est soustrait) plutôt que 0x7FF
(2047 qui indique un NaN
ou un infini). 0xFFFFFFFFFFFFF
qui est de 52 bits tous 1. En binary, la valeur est l’implicite 1 suivie de 52 autres de la mantisse, puis de 971 zéros (1023 – 52 = 971) à partir de l’exposant.
La valeur décimale exacte est:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
C’est environ 1,8 x 10 308 .
Vous devez regarder la taille de la mantisse. Un nombre à virgule flottante IEEE 754 64 bits (qui comporte 52 bits, plus 1 implicite) peut représenter exactement des nombres entiers dont la valeur absolue est inférieure ou égale à 2 ^ 53.
1,7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
de
devrait donner une approximation raisonnable de cela. Comme il s’agit de chiffres décimaux, et qu’il est réellement stocké en binary, vous pouvez probablement stocker quelque chose d’un peu plus grand sans perdre en précision, mais à quel point c’est difficile à dire. Je suppose que vous devriez être capable de le comprendre à partir de FLT_RADIX
et DBL_MANT_DIG
, mais je ne suis pas sûr que je fasse complètement confiance au résultat.