il più grande numero intero che può essere memorizzato in un doppio


Risposte:


506

L'intero più grande / più grande che può essere memorizzato in un doppio senza perdere precisione è lo stesso del valore più grande possibile di un doppio. Cioè, DBL_MAXo circa 1,8 × 10 308 (se il doppio è un doppio IEEE 754 a 64 bit). È un numero intero. È rappresentato esattamente. Che cosa vuoi di più?

Dai, chiedimi qual è il numero intero più grande, in modo tale che esso e tutti i numeri più piccoli possano essere memorizzati in IEEE a 64 bit doppi senza perdere precisione. Un doppio IEEE a 64 bit ha 52 bit di mantissa, quindi penso che sia 2 53 :

  • 2 53 + 1 non possono essere memorizzati, perché 1 all'inizio e 1 alla fine hanno troppi zeri in mezzo.
  • Qualsiasi cosa inferiore a 2 53È possibile memorizzare , con 52 bit esplicitamente memorizzati nella mantissa, e quindi l'esponente in effetti dandone un altro.
  • 2 53 ovviamente possono essere memorizzati, dato che è una piccola potenza di 2.

O un altro modo di vederlo: una volta che il bias è stato rimosso dall'esponente e ignorato il bit del segno come irrilevante per la domanda, il valore memorizzato da un doppio è una potenza di 2, più un intero di 52 bit moltiplicato per 2 esponente - 52 . Quindi con l'esponente 52 è possibile memorizzare tutti i valori da 2 52 a 2 53  - 1. Quindi con l'esponente 53, il numero successivo che è possibile memorizzare dopo 2 53 è 2 53 + 1 × 2 53 - 52 . Quindi la perdita di precisione si verifica prima con 2 53 + 1.


126
+1 Un buon lavoro nel notare che la domanda non significava davvero cosa intendesse probabilmente il richiedente e fornire entrambe le risposte ("tecnicamente corretto" e "probabilmente previsto").
Pascal Cuoq,

62
O "scherzare" e "cercare di aiutare" come tendo a chiamarli :-)
Steve Jessop,

8
Mi inchino a Tony il Pony e nessun altro.
Steve Jessop,

11
Non intendi "tutti i numeri interi più piccoli", intendi tutti i numeri interi di grandezza uguale o minore. Perché ci sono molti numeri negativi sotto sotto 2 ^ 53 e non possono essere rappresentati esattamente in un doppio.
Ospitalità meridionale,

13
Intendo più piccolo, ed è esattamente ciò che intendo quando dico più piccolo :-) -1.000.000 è inferiore a 1, ma non è più piccolo.
Steve Jessop,

77

9007199254740992 (sono 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

7
Supponendo che sarà "vicino" ma inferiore a 2 ^ N, quindi un test più veloce è double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);che produce lo stesso risultato
Seph

4
@Seph cosa ... No? while (dbl == --dbl)eseguirà il loop per sempre o per niente. :) (in questo caso, per niente, dato che è un 2 ^ N). Dovrai avvicinarti dal basso. Ne risulterà sicuramente anche uno in meno del risultato previsto (dal momento che quello verifica nel ciclo while diminuisce dbl). E dipende dall'ordine di esecuzione, se il decremento viene eseguito prima o dopo aver valutato il lato sinistro (che non è definito per quanto ne so). Se è il primo, sarà sempre vero e continuerà per sempre.
falstro,

10
Forse indicare che 2 ^ 53 = 9.007.199.254.740.992 da qualche parte.
Xonatron,

1
È difficile discutere con questo! Bel esperimento
MattM,

Una debolezza nell'uso while (dbl + 1 != dbl) dbl++;che dbl + 1 != dblpuò valutare l'utilizzolong double matematica - considera FLT_EVAL_METHOD == 2. Questo potrebbe finire in un ciclo infinito.
chux - Ripristina Monica il

25

Wikipedia ha questo da dire nello stesso contesto con un link a IEEE 754 :

Su un tipico sistema informatico, un numero in virgola mobile binario a "doppia precisione" (64 bit) ha un coefficiente di 53 bit (di cui uno implicito), un esponente di 11 bit e un bit di segno.

2 ^ 53 è poco più di 9 * 10 ^ 15.


@Steve Jessop più o meno, è proprio quello che sto dicendo. Ho anche incontrato sistemi hardware che non hanno una FPU che devono ancora essere conformi allo standard IEEE, quindi le cose "tipiche del sistema" non mi aiutano davvero se torno qui 8 mesi dopo e ho bisogno delle stesse informazioni per il mio microcontrollore basato su 68K (supponendo che non abbia una FPU ... non ricordo).
San Jacinto,

14
@San Jacinto - "Questo è inutile" è eccessivamente duro. La risposta è abbastanza utile, ma non altrettanto utile come sarebbe stata se includesse il commento che i sistemi informatici tipici usano effettivamente la ripensazione IEEE 754.
Stephen C. Steel,

@Stephen C. Steel, in realtà hai ragione. Nel mio scenario, tornando a questo in un secondo momento e cercando l'IEEE max, è incredibilmente ambiguo su cosa sia un "sistema tipico", ma c'è ancora del merito nella risposta oltre a questa lamentela.
San Jacinto,

20

Il numero intero più grande che può essere rappresentato in IEEE 754 double (64-bit) è uguale al valore più grande che il tipo può rappresentare, poiché quel valore è esso stesso un numero intero.

Questo è rappresentato come 0x7FEFFFFFFFFFFFFF, che è composto da:

  • Il bit di segno 0 (positivo) anziché 1 (negativo)
  • L'esponente massimo 0x7FE(2046 che rappresenta 1023 dopo la sottrazione del bias) anziché 0x7FF(2047 che indica a NaNo infinito).
  • La mantissa massima 0xFFFFFFFFFFFFFche è 52 bit tutti 1.

In binario, il valore è 1 implicito seguito da altri 52 dalla mantissa, quindi 971 zeri (1023 - 52 = 971) dall'esponente.

Il valore decimale esatto è:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

Si tratta di circa 1,8 x 10 308 .


Che dire del valore più grande che può rappresentare con tutti i valori tra esso e zero rappresentabili in modo contiguo?
Aaron Franke il

@AaronFranke La domanda non riguardava la rappresentazione contigua, ma la risposta a quella diversa domanda è stata inclusa nella maggior parte delle altre risposte qui, o addirittura erroneamente data come risposta effettiva. È 2⁵³ (2 alla potenza di 53).
Simon Biber,

8

Devi guardare le dimensioni della mantissa. Un numero in virgola mobile IEEE 754 a 64 bit (che ha 52 bit, più 1 implicito) può rappresentare esattamente numeri interi con un valore assoluto inferiore o uguale a 2 ^ 53.


8
Può rappresentare esattamente anche 2 ^ 53 :-)
Steve Jessop il

6

2
questa risposta sarebbe molto meglio con una citazione.
San Jacinto,

2
@Carl bene, se l'intero ha zeri oltre a sinistra, viene memorizzato con precisione.
Wilhelm,

4
@tutti voi downvoter: 1.7976931348623157 × 10 ^ 308 è un numero intero esatto. Avete tutti bisogno di frequentare le lezioni di matematica correttive o qualcosa del genere?
Dan Molding,

6
Siamo giù alla semantica qui nella discussione di questa risposta irrimediabilmente affondata. È vero, quel numero può essere rappresentato esattamente e quindi soddisfa la lettera della domanda. Ma sappiamo tutti che è una minuscola isola di esattezza in un oceano di quasi-miss, e la maggior parte di noi ha correttamente interpolato la domanda per indicare "il numero più grande oltre il quale la precisione scende." Ah, non è meraviglioso che CompSci sia una scienza esatta? :)
Carl Smotricz il

2
@DanMoulding 1.7976931348623157 × 10 ^ 308 è un numero intero esatto, ma sono abbastanza sicuro che questo numero intero non possa essere memorizzato esattamente in un doppio.
Pascal Cuoq,

2

DECIMAL_DIGda <float.h>dovrebbe fornire almeno una ragionevole approssimazione di ciò. Dal momento che si occupa di cifre decimali ed è davvero memorizzato in binario, probabilmente puoi memorizzare qualcosa di un po ' più grande senza perdere precisione, ma esattamente quanto è difficile da dire. Suppongo che dovresti essere in grado di capirlo da FLT_RADIXe DBL_MANT_DIG, ma non sono sicuro che mi fiderei completamente del risultato.


Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti a un autore, lascia un commento sotto il suo post.
MichaelChirico,

@MichaelChirico: questo risponde alla domanda che intendeva porre, come esisteva quando la risposta è stata scritta. Per visualizzare la cronologia delle modifiche della domanda, fai clic sul link "modificato del 19 giugno 14 alle 11:40" nella parte inferiore della domanda.
Jerry Coffin,

la tua risposta si legge come un commento perché sembra mancare della fiducia / autorevolezza che una risposta dovrebbe avere ("dovrebbe dare almeno un ragionevole ..." "esattamente quanto ... è difficile da dire" "Suppongo ... "). Non ho esperienza sulla domanda o sulla risposta, quindi potrei sbagliarmi; inserendo solo i miei due centesimi dato che sono stato inviato qui dalla coda di revisione (che immagino significhi che altri utenti hanno segnalato la tua risposta).
MichaelChirico,

1
@MichaelChirico: Potrebbero anche averlo - sei ben lungi dall'essere l'unico che ignora l'argomento; ciò che ti rende insolito è che ti rendi conto di esserne ignaro. La maggior parte delle risposte che sembrano autorevoli sulla precisione di un numero in virgola mobile in C sono semplicemente errate. Ad esempio, molti (la maggior parte) di cui sopra si basano sul falso presupposto che a doublecorrisponda direttamente a uno specifico tipo IEEE, ma ciò non è necessario e quando questa risposta è stata scritta la domanda non menzionava nemmeno un particolare tipo IEEE.
Jerry Coffin

fatto. Forse suggerirei di aggiungere quelle informazioni alla risposta.
MichaelChirico,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.