2011-10-14 13 views
19

ho controllato il documento che long = int64 ha gamma più di 900.000.000.000.000perché questo comporterebbe a lungo integer overflow

Ecco il mio codice:

int r = 99; 
long test1 = r*r*r*r*r; 

in fase di esecuzione mi dà 919.965.907 al posto del corretto 9.509.900,499 mila.

un altro test

long test2 = 99*99*99*99*99; 

si rifiuta di compilare, dicendo integer overflow.

Ma se faccio questo

long test3 = 10100200300; 

Questo funziona bene.

risposta

48

Il problema è che il letterale "99" viene trattato come un int. Se aggiungi "L" lo tratterà come un lungo. Per risolvere il problema la compilazione:

long test2 = 99L * 99L * 99L * 99L * 99L; 

E per risolvere il "risultato non corretto" causato dalla integer overflow:

long r = 99; 
long test1 = r * r * r * r * r; 

Il punto chiave è che l'espressione a destra del "=" viene valutata prima del l'assegnazione a long r è terminata.

Ci sono altri suffissi letterali potreste essere interessati a:

Type Suffix Example 
uint U or u 100U 
long L or l 100L 
ulong UL or ul 100UL 
float F or f 123.45F 
decimal M or m 123.45M 

@ m.edmonson, per quanto riguarda la tua domanda sul perché si esce a 919965907. Che succede, è che il valore è "wrapping" in giro int.MaxValue. Potete vedere questo con un piccolo programma di test:

int i = 99; // 99 
i *= 99; // 9801 
i *= 99; // 970299 
i *= 99; // 96059601 
i *= 99; // 919965907  should be 9509900499 but comes out to 919965907 
      //      which is (9509900499 % int.MaxValue) 

long k = 9509900499 % int.MaxValue; 

Cosa si intende per "involucro"? Se si supera int.MaxValue per 1, il valore "torna" a int.MinValue.

int j = int.MaxValue; 
j++; 

bool isNowMinValue = (j == int.MinValue); // true, the value has "wrapped around" 

Questo è un po 'semplicistico; se cerchi "overflow intero" otterrai una spiegazione migliore. Vale la pena di comprendere come numeri interi (e altri tipi numerici) sono rappresentati con 32 bit:

http://en.wikipedia.org/wiki/Signed_number_representations

+0

Risposta eccellente - puoi spiegare perché lui ottiene un risultato diverso tra la moltiplicazione lunga e quella intera? –

+0

Puoi chiarire cosa intendi avvolgendo? E cosa c'entra con il modulo%? –

+0

Credo che tu abbia bisogno solo di un '99L', il resto sarà trasmesso. –

5

Si utilizza intero moltiplicazione:

long r = 99; 
long test1 = r*r*r*r*r; 
3

Il secondo test fallisce perchè ogni 99 è un numero intero; sostituirlo con il seguente e compila.

long test2 = 99L * 99L * 99L * 99L * 99L; 

Vedere il MSDN Long Documentation per dettagli.

1

Il compilatore considera 99 come numeri interi, anche se il risultato finale sarà lungo.

Questo funzionerà.

long test2 = 99L*99L*99L*99L*99L; 
4

Come l'altro hanno detto, ma:

long test2 = 99L * 99 * 99 * 99 * 99; 

Questo vi darà il risultato corretto con meno L intorno :-)

Questo accade perché la prima 99L è un long, quindi tutte le moltiplicazioni sono fatte nel "campo" long e tutti gli altri numeri interi sono trasmessi a long prima della moltiplicazione (chiaramente la moltiplicazione è sempre tra 2 numeri e va da sinistra a destra, quindi è come (((99L * 99) * 99) * 99) * 99 e ogni risultato "parziale" è lungo e fa convertire l'operando successivo a lungo.)

Problemi correlati