2008-09-29 5 views

Respuesta

11
#include <stdint.h> 
#include <stdio.h> 

union ui64 { 
    uint64_t one; 
    uint16_t four[4]; 
}; 

int 
main() 
{ 
    union ui64 number = {0x123456789abcdef0}; 
    printf("%x %x %x %x\n", number.four[0], number.four[1], 
          number.four[2], number.four[3]); 
    return 0; 
} 
+0

¿Esto podría estar influenciado por little/big-endian? – slashmais

+0

Sí, se obtienen resultados diferentes para los sistemas big-endian frente a los little-endian. –

+0

Definitivamente es una solución rápida y estrafalaria, en el mismo orden que: "@numbers = unpack 'S4', paquete 'Q', $ number;" en Perl –

2
union LongLongIntToThreeUnsignedShorts { 
    long long int long_long_int; 
    unsigned short int short_ints[sizeof(long long int)/sizeof(short int)]; 
}; 

Eso debería hacer lo que está pensando, sin tener que perder el tiempo con desplazamiento de bits.

+0

¿Se puede garantizar que la estructura no tendrá relleno entre entradas cortas? – Alexander

+0

buen punto. El método de matriz sería más sensato. – workmad3

+0

Ooops - Originalmente escribí sobre tres ints sin firmar. Eso probablemente te engañe. Lo siento por eso. Tu respuesta fue útil de todos modos. –

3
(unsigned short)((((unsigned long long int)value)>>(x))&(0xFFFF)) 

donde value es su long long int y x es 0, 16, 32 o 48 para los cuatro cortos.

+0

La captura con cambio de bits es que en C/C++ el comportamiento no está definido para números negativos. – Alexander

+0

El "valor" negativo no está indefinido, está definido por la implementación. Para la "x" negativa no está definida, pero eso nunca sucede aquí. Y el formato de almacenamiento de un entero negativo también está definido por la implementación (dentro de ciertas posibilidades), por lo tanto, en este aspecto, esto no es peor que el uso de una unión. –

+0

No me importa si el signo de cambio: amplía el valor, estoy enmascarando todos menos los dieciséis bits inferiores. Esos están bien definidos. – moonshadow

Cuestiones relacionadas