2012-04-06 22 views
6

tengo este código en C (que es para el estudio solamente):C desplazamiento a la izquierda en 64 bits de fallar

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);   
    }  

lo que se imprime:

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

Por qué en x> 26 tengo que aquellos valores extraños? Estoy en gcc 4.6.1 en Ubuntu 10.10 64 bits.

+0

parece que el problema está en char x, lo utilicé uint64_t y funciona bien. –

+0

Podrá ver más claramente lo que sucede si 'total = ((((1 << x) * x)/64) + 1) * sizeof (uint64_t));' se simplifica a 'total = ((1 << x) * x); 'luego imprimido con' printf ("% d - 0x% llx \ n", x, total); 'verá el bit del signo que está dando negativo al nmber, que se imprime como un gran número por printf ("... -% llu \ n", ... total); – gbulmer

Respuesta

18

Porque 1 es int, 32 bits, por lo que (1 << 27)*27 se desborda. Use 1ull.

En cuanto a su comentario, si x es una uint64_t, entonces 1 << x sigue siendo una int, sino por la multiplicación sería arrojado a uint64_t, por lo que no habría ningún desbordamiento. Sin embargo, si x >= 31, 1 << x sería un comportamiento indefinido (ya que el valor resultante no se puede representar mediante un tipo entero de 32 bits con signo).

+0

¡Eso es hombre! ¡Gracias! –

0

supongo es su problema, se calcula con 32 bits y asignar más tarde a un valor de 64 bits

división por 64 es lo mismo que no cambiará de 6 bits

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);   
} 

no compilados todavía

Cuestiones relacionadas