Захватив n бит из байта

У меня небольшие проблемы с получением n битов из байта.

У меня есть целое число без знака. Допустим, наше число в шестнадцатеричном формате равно 0x2A, что составляет 42 в десятичном виде. В двоичном виде это выглядит так: 0010 1010. Как бы я взял первые 5 битов, которые являются 00101, и следующие 3 бита, которые являются 010, и поместил бы их в отдельные целые числа?

Если бы кто-нибудь мог мне помочь, это было бы здорово! Я знаю, как извлечь из одного байта, который должен просто сделать

int x = (number >> (8*n)) & 0xff // n being the # byte

что я видел в другом посте о переполнении стека, но я не был уверен, как извлечь отдельные биты из байта. Если бы кто-нибудь мог мне помочь, это было бы здорово! Спасибо!

12

Решение

Целые числа представлены внутри машины в виде последовательности битов; К счастью для нас, людей, языки программирования предоставляют механизм, который показывает нам эти числа в десятичной (или шестнадцатеричной) форме, но это не меняет их внутреннего представления.

Вы должны пересмотреть побитовые операторы &, |, ^ а также ~ а также операторы сдвига << а также >>, который поможет вам понять, как решить такие проблемы.

Последние 3 бита целого числа:

x & 0x7

Пять битов, начиная с восьмого последнего бита:

x >> 3    // all but the last three bits
&  0x1F // the last five bits.
17

Другие решения

«захват» частей целочисленного типа в C работает так:

  1. Вы сдвигаете нужные биты в самое низкое положение.
  2. Ты используешь & чтобы замаскировать нужные биты — одни означают «скопировать этот бит», нули — «игнорировать»

Итак, в вашем примере. Допустим, у нас есть номер int x = 42;

первые 5 бит:

(x >> 3) & ((1 << 5)-1);

или же

(x >> 3) & 31;

Чтобы получить младшие три бита:

(x >> 0) & ((1 << 3)-1)

или же:

x & 7;
12

Скажи, что ты хочешь hi биты сверху и lo биты снизу. (5 и 3 в вашем примере)

top = (n >> lo) & ((1 << hi) - 1)
bottom = n & ((1 << lo) - 1)

Объяснение:

Для Топ, сначала избавьтесь от младших битов (сдвиг вправо), затем замаскируйте оставшиеся маской «все единицы» (если у вас есть двоичное число, например 0010000вычитая один результат 0001111 — такое же количество 1с как ты 0в оригинальном номере).

Для дна это то же самое, просто не нужно заботиться о начальном смещении.

top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b
8

Вы можете использовать битовые поля для этого. Битовые поля — это специальные структуры, в которых вы можете указывать переменные в битах.

typedef struct {
unsigned char a:5;
unsigned char b:3;
} my_bit_t;

unsigned char c = 0x42;
my_bit_t * n = &c;
int first = n->a;
int sec = n->b;

Битовые поля описаны более подробно на http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

Прелесть битовых полей в том, что вам не нужно иметь дело с операторами сдвига и т. Д. Обозначение довольно простое. Как всегда, при работе с битами возникает проблема переносимости.

5

просто избавьтесь от 8 * в вашем коде.

int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)
1

int x = (number >> 3) & 0x1f;

даст вам целое число, где последние 5 бит являются 8-4 битами number и нули в других битах.

Так же,

int y = number & 0x7;

даст вам целое число с последними 3 битами, установите последние 3 бита number и нули в остальном.

1
По вопросам рекламы [email protected]