Как читать отдельные биты из массива? - PullRequest
5 голосов
/ 21 марта 2011

Допустим, у меня есть массив, динамически выделяемый.

int* array=new int[10]

Это 10 * 4 = 40 байт или 10 * 32 = 320 бит. Я хочу прочитать 2-й бит 30-го байта или 242-й бит. Какой самый простой способ сделать это? Я знаю, что могу получить доступ к 30-му байту, используя массив [30], но доступ к отдельным битам более сложен.

Ответы [ 6 ]

6 голосов
/ 21 марта 2011
bool bitset(void const * data, int bitindex) {
  int byte = bitindex / 8;
  int bit = bitindex % 8;
  unsigned char const * u = (unsigned char const *) data;
  return (u[byte] & (1<<bit)) != 0;
}
1 голос
/ 21 марта 2011

Во-первых, если вы выполняете побитовые операции, это обычно предпочтительнее сделать элементы целочисленного типа без знака (хотя в этом случае, это действительно не так уж много разница). Что касается доступа к битам: для доступа к биту I в массив из n int:

static int const bitsPerWord = sizeof(int) * CHAR_BIT;
assert( i >= 0 && i < n * bitsPerWord );
int wordIndex = i / bitsPerWord;
int bitIndex = i % bitsPerWord;

затем читать:

return (array[wordIndex] & (1 << bitIndex)) != 0;

установить:

array[wordIndex] |= 1 << bitIndex;

и сбросить:

array[wordIndex] &= ~(1 << bitIndex);

Или вы можете использовать битовый набор, если n является постоянным, или vector<bool>, или boost::dynamic_bitset если это не так, и пусть кто-то другой сделает работа.

1 голос
/ 21 марта 2011

это работает!

#define GET_BIT(p, n) ((((unsigned char *)p)[n/8] >> (n%8)) & 0x01)

int main()
{
    int myArray[2] = { 0xaaaaaaaa, 0x00ff00ff };
    for( int i =0 ; i < 2*32 ; i++ )
        printf("%d", GET_BIT(myArray, i));
    return 0;
}

Выход:

010101010101010101010101010101011111111100000111111111000000111111110000001111111100000000

Будьте осторожны с endiannes!

0 голосов
/ 21 марта 2011

Здесь нужны битовые операции ...

if(array[5] & 0x1)
{
//the first bit in array[5] is 1
}
else
{
//the first bit is 0
}

if(array[5] & 0x8)
{
//the 4th bit in array[5] is 1
}
else
{
//the 4th bit is 0
}

0x8 - 00001000 в двоичном формате. Выполнение anding маскирует все остальные биты и позволяет увидеть, равен ли бит 1 или 0.

int обычно составляет 32 бита, поэтому вам нужно выполнить некоторую арифметику, чтобы получить определенное число бит во всем массиве.

0 голосов
/ 21 марта 2011

Вы можете использовать что-то вроде этого:

!((array[30] & 2) == 0)

массив [30] является целым числом.

& 2 является иоперация, которая маскирует второй бит (2 = 00000010)

== 0 , проверит, является ли результат маски 0

! , что приведет к отрицанию того, чторезультат, потому что мы проверяем, если 1 не ноль ....

0 голосов
/ 21 марта 2011

РЕДАКТИРОВАНИЕ на основе комментария ниже - массив содержит 32-битное целое, а не 8-битное учар.

int pos = 241; // I start at index 0
bool bit242 = (array[pos/32] >> (pos%32)) & 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...