2012-04-06 15 views
5

Preguntas muy simples chicos, pero tal vez me estoy olvidando de algo. En 64 bits de Linux, ¿una longitud de 8 bytes es correcta? Si ese es el caso, y quiero establecer el bit 64, que puede hacer lo siguiente:Long type 64bit linux

unsigned long num = 1<<63; 

Siempre que puedo compilar esto, sin embargo, me da un error que dice que estoy izquierda cambiando en más de la anchura. Además, si quería dar los primeros 32 bits de un tipo de largo (sin extensión de signo), puedo hacer:

num = num&0xFFFFFFFF; 

o ¿qué pasa con:

num = (int)(num); 

Gracias.

+5

Probar: 'unsigned long num = 1UL << 63;' – Mysticial

+0

@Mysticial Por qué no publicar que como una respuesta junto con el material de promoción número entero? – cnicutar

+1

Depende de qué compilador se use. Muchos compiladores heredados tendrían valores predeterminados de 32 bits, incluso si se ejecutan en una máquina de 64 bits. Confirma que 'sizeof num' es 8 antes de intentar algo más. – wallyk

Respuesta

3

En Linux de 64 bits, es un largo 8 bytes correcto?

No necesita ser. Depende del compilador que del sistema operativo subyacente. Mira esto para una buena discusión. What decides the sizeof an integer?

Siempre que puedo compilar esto, sin embargo, me da un error que dice que soy izquierda cambiando en más de la anchura

Todo el mundo ya han respondido a esta. Utilice 1UL

Además, si quería dar los primeros 32 bits de tipo largo de (sin extensión de signo), puedo hacer:

num = num&0xFFFFFFFF; 
or what about: 

num = (int)(num); 

num = num&0xFFFFFFFF. Esto le dará los 32 bits más bajos. Pero tenga en cuenta que si long tiene solo 4 bytes en su sistema, entonces obtendrá el número entero. Viniendo a la parte de extensión de signo, si has usado un long y no unsigned long, entonces no puedes eliminar el signo de bits extendidos. Por ejemplo, -1 se representa como todos, directamente desde el 0º bit. ¿Cómo vas a evitar estos enmascarando?

num = (int)(num) le dará la baja de 32-bits, pero el compilador podría a través de un aviso de desbordamiento de excepción si num no encaja en un código de AFAIR int

+0

Acepta que C no impone 'long' a ser 64bits en una máquina de 64bits. Sin embargo, Linux lo impone implícitamente. Solo eche un vistazo a todos los punteros que pasaron a través de 'unsigned long' y los desplazamientos de memoria pasaron a través de' signed long' (por ejemplo, syscalls). Por lo tanto, siempre que el código fuente de Linux no cambie drásticamente, respondería ** sí ** a la pregunta: "En 64 bits de Linux, un' largo 'es de 8 bytes, ¿correcto? " –

0

Creo que el problema con la primera pregunta es que el compilador está tratando '1' como un entero, no como un entero largo. No lo resuelve hasta después de la asignación.

se puede arreglar haciendo:

unsigned long num = (unsigned long)1<<63; 
+0

¿Conoces la respuesta a la segunda parte de mi pregunta? ¿Sobre obtener los primeros 32 bits sin signo extendido? ¿Haría algo similar a num = num & (unsigned long) (0xFFFFFFFF)? – de1337ed

+0

@ de1337ed He respondido la segunda parte de tu Qn. Consulte –

4

En realidad, si quieres un poco de longitud precisa (en bits) para sus números enteros, asumiendo un compilador C99 conforme, #include <stdint.h> y utilizar tipos como int64_t, int32_t etc. un tipo práctico es intptr_t, un tipo entero con el mismo número de bits como void* puntero (por lo que se le puede llamar una "palabra" máquina)

+1

Un compilador conforme C99 no necesita proporcionar tipos de ancho fijo, p. 'int64_t'. Solo las implementaciones de dos complementos que proporcionan tipos de enteros de 8, 16, 32 y 64 bit sin bits de relleno son * obligatorios * para proporcionar tipos de enteros de ancho fijo en 'stdint.h'. – dreamlax

1

Para un transporte puede usar:

limits.h

#define LNG_BIT (sizeof(long) * CHAR_BIT) 

unsigned long num = 1UL << (LNG_BIT - 1); 

Para conseguir "baja int", algo así como ?:

#define INT_BIT (sizeof(int) * CHAR_BIT) 

if (LNG_BIT > INT_BIT) 
    return num & (~0UL >> INT_BIT); 
else 
    return num; 

o

num &= ~(~0U << INT_BIT); 

O, la máscara de uso, Depende en gran medida de por qué, para qué, etc. los bits int.

También tenga en cuenta las opciones dadas por los compiladores; Es decir. Si se está empleando gcc:

-m32
-m64
-mx32
        generar código de 32 bits o Entorno de 64 bits.
        * La opción -m32 establece los tipos int, long y pointer en 32 bits y genera código que se ejecuta en cualquier sistema i386.
        * La opción -m64 establece int a 32 bits y long y tipos de puntero a 64 bits, y genera código para la arquitectura x86-64. Para Darwin solo la opción -m64 también desactiva las opciones -fno-pic y -mdinámica-no-pic.
        * La opción -mx32 establece los tipos int, long y pointer en 32 bits y genera código para la arquitectura x86-64.

También hay -maddress-mode=long etc.

-maddress-mode = larga
        Generar código para el modo de dirección larga. Esto solo es compatible con entornos de 64 bits y x32. Es el modo de dirección predeterminado para entornos de 64 bits.

0

como esto era la fuente de un error importante en reiserfs hace unos años :

unsigned long num = 1<<63; 

Si habla de x86_64, sí, mucho es de 64 bits y en la mayoría de los otros plytforms 64 bits de Linux también.El problema es que tanto el 1 como el 63 en su código son simples int, por lo que el resultado no está definido. Mejor utilizar

unsigned long num = 1UL<<63; 

o

unsigned long num = (unsigned long)1<<63;