2010-08-11 2 views
7

Если у меня есть указатель на начало области памяти, и мне нужно прочитать значение, упакованное в биты 30, 31 и 32 этой области, как я могу прочитать это значение?Чтение бит в памяти

ответ

3

Это зависит от того, насколько большой байт в вашей машине. Ответ будет зависеть от того, если вы ноль или один индекс для этих чисел. Следующая функция возвращает 0, если бит равен 0 и не равно нулю, если это 1.

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

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

Если ваш компилятор не может оптимизировать достаточно хорошо, чтобы включить разделение и ультрасовременные операции в битовые операции, вы можете сделать это явно, но я предпочитаю этот код для ясности.

(ред исправить ошибку и изменить к CHAR_BIT, что это отличная идея.)

+0

Используйте 'CHAR_BIT' вместо 8. – GManNickG

+0

В случае, если это не будет:' Возвращение буфера [byte] & (1 << бит); '? Похоже, вы разрешаете слишком много бит, если (например) бит == 3. –

+0

@platinum yup. Ввод слишком быстро. Фиксация сейчас. –

0

В 32-разрядной системе вы можете просто сдвинуть указатель справа 29. Если вам нужны значения бит на месте и 0xE0000000.

1

я бы, вероятно, generalize this answer к чему-то вроде этого:

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

бит проще в использовании:

int i = 12345; 
bool abit = get_bit(i, 4); 
Смежные вопросы