2012-04-06 10 views
6

Ho questo codice in C (è per lo studio solo):C spostamento a sinistra di 64 bit fallire

char x; 
    uint64_t total = 0; 

    for(x = 20; x < 30; x++){ 
     total = (((((1 << x) * x)/64) + 1) * sizeof(uint64_t)); 
     printf("%d - %llu\n", x, total);   
    }  

ciò che è stampato:

20 - 2621448 
21 - 5505032 
22 - 11534344 
23 - 24117256 
24 - 50331656 
25 - 104857608 
26 - 218103816 
27 - 18446744073625665544 
28 - 18446744073575333896 
29 - 18446744073508225032 

Perchè per x> 26 devo quelli strani valori? Sono a gcc 4.6.1 su Ubuntu 10.10 64 bit.

+0

sembra che il problema sia in char x, ho usato uint64_t per questo e funziona bene. –

+0

Sarai in grado di vedere cosa sta accadendo più chiaramente se 'total = (((((1 << x) * x)/64) + 1) * sizeof (uint64_t));' è semplificato in 'total = ((1 << x) * x); 'stampato con' printf ("% d - 0x% llx \ n", x, totale); 'vedrai il bit del segno che gira il negativo nmber, che viene stampato come un numero enorme per printf ("... -% llu \ n", ... totale); – gbulmer

risposta

18

Perché 1 è un int, 32 bit, quindi overflow (1 << 27)*27. Utilizzare 1ull.

Per quanto riguarda il tuo commento, se x è un uint64_t, poi 1 << x è ancora un int, ma per la moltiplicazione sarebbe gettato a uint64_t, quindi non ci sarebbe troppo pieno. Tuttavia, se x >= 31, 1 << x sarebbe un comportamento non definito (poiché il valore risultante non può essere rappresentato da un tipo intero a 32 bit con segno).

+0

Ecco fatto! Grazie! –

0

Credo che il vostro problema è, si calcola con 32 bit e assegnare un secondo momento per un valore di 64 bit

divisione per 64 è lo stesso che non sposterà a 6 bit

char x; 
uint64_t one = 1; 
uint64_t total = 0; 

for(x = 20; x < 30; x++){ 
    total = ((((one << (x - 6)) * x) + 1) * sizeof(uint64_t)); 
    printf("%d - %llu\n", x, total);   
} 

non ancora compilato

Problemi correlati