2010-03-16 19 views
5

Por favor ver el código simple a continuación:sin signo de longitud con valor negativo

#include <iostream> 
#include <stdlib.h> 

using namespace std; 


int main(void) 
{ 
    unsigned long currentTrafficTypeValueDec; 
    long input; 
    input=63; 
    currentTrafficTypeValueDec = (unsigned long) 1LL << input; 
    cout << currentTrafficTypeValueDec << endl; 
    printf("%u \n", currentTrafficTypeValueDec); 
    printf("%ld \n", currentTrafficTypeValueDec); 
    return 0; 
} 

Por qué printf() muestra el currentTrafficTypeValueDec (largo sin signo) con valor negativo?

La salida es:

9223372036854775808 
0 
-9223372036854775808 

Respuesta

3

Diversión con trozos ...

cout está imprimiendo el número como un largo sin signo, todos los 64 bits son significativos e imprimir como un entero binario sin signo (creo que el formato de aquí sería %lu).

printf(%u ... trata la entrada como un entero normal sin signo (32 bits?). Esto hace que los bits 33 a 64 caigan, dejando cero.

printf(%ld ... trata la entrada como un número firmado de 64 bits y simplemente lo imprime como tal.

Lo que puede resultar confuso acerca de la última printf es que da el mismo valor absoluto que cout, pero con un signo menos. Cuando se visualiza como un entero sin signo, todos los 64 bits son significativos para producir el valor entero. Sin embargo, para los números con signo, el bit 64 es el bit de signo. Cuando se establece el bit de signo (como se muestra en el ejemplo), indica que los 63 bits restantes deben tratarse como un número negativo representado en 2's compliment. Los números positivos se imprimen simplemente convirtiendo su valor binario a decimal. Sin embargo, para un número negativo sucede lo siguiente: Imprima un signo negativo, los bits XOR 1 a 63 con bits binarios '1', agregue 1 al resultado e imprima el valor sin signo. Al soltar el bit de signo (bit 64) terminas con 63 '0' bits, XORing con '1' bits te da 63 '1' bits, agregas +1 y todo cambia para darte un entero sin signo que tiene bit 64 establecido en '1' y el resto en '0' - que es lo mismo que obtienes con cout PERO, como un número negativo.

Una vez que haya trabajado por qué la explicación anterior es correcta también debe ser capaz de dar sentido a this

13

mentiste printf pasándolo a un valor sin signo, mientras que la especificación de formato dijo que sería firmado una.

+0

interesante forma de decirlo :) – Tim

17

%d es un formateador firmado. La reinterpretación de los bits de currentTrafficTypeValueDec (2 a la 63 potencia) como signed long arroja un valor negativo. Entonces printf() imprime un número negativo.

Quizás desee utilizar %lu?

1

la variable no tiene su tipo en sí misma. Usted especifica imprimir su tipo. Proveedores:

printf("%lu \n", currentTrafficTypeValueDec); 

porque ld meand firmaron hace tiempo que no es cierto.

5

Dado que está cambiando el 1 en el bit de signo de la variable. Cuando lo imprime como un valor firmado, es negativo.

+0

1, mejor respuesta. –

0

Está imprimiendo %ld, o un decimal con signo largo. Es por eso que está devolviendo un valor negativo.

Cuestiones relacionadas