il più grande numero intero che può essere memorizzato in un doppio
-
13-09-2019 - |
Domanda
Qual è il più grande "no-floating" integer che può essere memorizzato in un tipo di doppia IEEE 754, senza perdere di precisione?
Soluzione
Il più grande numero intero più grande / che può essere memorizzato in un doppio senza perdere precisione è la stessa come il più grande valore possibile di un doppio. Cioè, DBL_MAX
pari a circa 1,8 × 10 308 (se il doppio è un IEEE 754 a 64 bit doppio). Si tratta di un numero intero. Viene rappresentato esattamente. Cosa vuoi di più?
Vai avanti, mi chiedono che cosa è il più grande intero, tale da e tutti gli interi più piccoli può essere conservato in IEEE a 64 bit raddoppia senza perdere precisione. IEEE 64 bit ha doppio 52 bit della mantissa, quindi penso che sia 2 53 :
- 2 53 + 1 non può essere memorizzato, perché il 1 all'inizio e l'1 al termine hanno troppi zeri in mezzo.
- Qualsiasi cosa meno di 2 53 possono essere memorizzati, con 52 bit esplicitamente memorizzati nella mantissa, e poi l'esponente in effetti dando un altro.
- 2 53 , ovviamente, possono essere memorizzati, in quanto si tratta di una piccola potenza di 2.
O un altro modo di vedere le cose: una volta che il bias è stato tolto l'esponente, e ignorando il bit di segno come irrilevante per la questione, il valore memorizzato da una doppia è una potenza di 2, oltre a un numero intero a 52 bit moltiplicato per 2 esponente - 52 . Quindi, con l'esponente 52 è possibile memorizzare tutti i valori da 2 52 fino al 2 53 - 1. Poi con esponente 53, il numero successivo è possibile memorizzare dopo 2 53 è di 2 53 + 1 × 2 53-52 . Così perdita di precisione prima verifica con 2 53 + 1.
Altri suggerimenti
9007199254740992 (che è 9,007,199,254,740,992) senza garanzie:)
Programma
#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;
}
Risultato
9007199254740991 9007199254740992 9007199254740992
Wikipedia ha questo da dire nello stesso contesto con un link a IEEE 754 :
In un sistema tipico computer, un 'doppia precisione' (64-bit) numero binario a virgola mobile ha un coefficiente di 53 bit (uno dei quali è implicito), esponente di 11 bit, e un bit di segno.
2 ^ 53 è poco più del 9 * 10 ^ 15.
Il numero intero più grande che può essere rappresentato in IEEE 754 doppia (64 bit) è uguale al valore più grande che il tipo può rappresentare, in quanto tale valore è esso stesso un numero intero.
Questo è rappresentato come 0x7FEFFFFFFFFFFFFF
, che si compone di:
- Il bit di segno 0 (positivo) anziché 1 (negativo)
- Il
0x7FE
massimo esponente (2046 che rappresenta 1023 dopo la polarizzazione viene sottratto) piuttosto che0x7FF
(2047 che indica unNaN
o infinito). - Il massimo
0xFFFFFFFFFFFFF
mantissa che è 52 bit tutti 1.
In binario, il valore è implicito 1 seguiti da altri 52 quelli della mantissa, poi 971 zeri (1023 - 52 = 971). Dal esponente
Il valore decimale esatto è:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Questo è approssimativamente 1,8 x 10 308 .
È necessario guardare la dimensione della mantissa. IEEE 754 numero a 64 bit floating point (che ha 52 bit, più 1 implicita) possono rappresentare esattamente interi con un valore assoluto inferiore o uguale a 2 ^ 53.
1,7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
da <float.h>
dovrebbe dare almeno una ragionevole approssimazione di quella. Dal momento che si occupa di cifre decimali, ed è davvero memorizzato in formato binario, probabilmente si può memorizzare qualcosa di un piccolo più grande senza perdere in precisione, ma esattamente quanto è difficile da dire. Suppongo che si dovrebbe essere in grado di capirlo da FLT_RADIX
e DBL_MANT_DIG
, ma non sono sicuro mi fiderei completamente il risultato.