2010-08-11 16 views
7

Si tengo un puntero al inicio de una región de memoria, y necesito leer el valor empaquetado en los bits 30, 31 y 32 de esa región, ¿cómo puedo leer ese valor?Lectura de bits en una memoria

Respuesta

3

Depende de qué tan grande es un byte en su máquina. La respuesta variará dependiendo de si tiene cero o una indexación para esos números. La siguiente función devuelve 0 si el bit es 0 y distinto de cero si es 1.

int getBit(char *buffer, int which) 
{ 
    int byte = which/CHAR_BIT; 
    int bit = which % CHAR_BIT; 

    return buffer[byte] & (1 << bit); 
} 

Si el compilador no puede optimizar lo suficientemente bien como para activar la división y operaciones mod en operaciones de bits, que podría hacerlo explícitamente, pero prefiero este código para mayor claridad.

(editado para corregir un error y cambiar a CHAR_BIT, que es una gran idea.)

+0

Use 'CHAR_BIT' en lugar de 8. – GManNickG

+0

En caso de no ser esto:' búfer de retorno [byte] & (1 << bit); '? Se siente como si permitieras pasar demasiados bits si (por ejemplo) bit == 3. –

+0

@platinum yup. Escribiendo muy rápido. Arreglando ahora. –

0

En un sistema de 32 bits, puede simplemente desplazar el puntero a la derecha 29. Si necesita los valores de bit en su lugar, y en 0xE0000000.

1

probablemente me generalize this answer a algo como esto:

template <typename T> 
bool get_bit(const T& pX, size_t pBit) 
{ 
    if (pBit > sizeof(pX) * CHAR_BIT) 
     throw std::invalid_argument("bit does not exist"); 

    size_t byteOffset = pBit/CHAR_BIT; 
    size_t bitOffset = pBit % CHAR_BIT; 

    char byte = (&reinterpret_cast<const char&>(pX))[byteOffset]; 
    unsigned mask = 1U << bitOffset; 

    return (byte & mask) == 1; 
} 

poco más fácil de usar:

int i = 12345; 
bool abit = get_bit(i, 4); 
Cuestiones relacionadas