У меня небольшие проблемы с получением n битов из байта.
У меня есть целое число без знака. Допустим, наше число в шестнадцатеричном формате равно 0x2A, что составляет 42 в десятичном виде. В двоичном виде это выглядит так: 0010 1010. Как бы я взял первые 5 битов, которые являются 00101, и следующие 3 бита, которые являются 010, и поместил бы их в отдельные целые числа?
Если бы кто-нибудь мог мне помочь, это было бы здорово! Я знаю, как извлечь из одного байта, который должен просто сделать
int x = (number >> (8*n)) & 0xff // n being the # byte
что я видел в другом посте о переполнении стека, но я не был уверен, как извлечь отдельные биты из байта. Если бы кто-нибудь мог мне помочь, это было бы здорово! Спасибо!
Целые числа представлены внутри машины в виде последовательности битов; К счастью для нас, людей, языки программирования предоставляют механизм, который показывает нам эти числа в десятичной (или шестнадцатеричной) форме, но это не меняет их внутреннего представления.
Вы должны пересмотреть побитовые операторы &
, |
, ^
а также ~
а также операторы сдвига <<
а также >>
, который поможет вам понять, как решить такие проблемы.
Последние 3 бита целого числа:
x & 0x7
Пять битов, начиная с восьмого последнего бита:
x >> 3 // all but the last three bits
& 0x1F // the last five bits.
«захват» частей целочисленного типа в C работает так:
&
чтобы замаскировать нужные биты — одни означают «скопировать этот бит», нули — «игнорировать»Итак, в вашем примере. Допустим, у нас есть номер int x = 42;
первые 5 бит:
(x >> 3) & ((1 << 5)-1);
или же
(x >> 3) & 31;
Чтобы получить младшие три бита:
(x >> 0) & ((1 << 3)-1)
или же:
x & 7;
Скажи, что ты хочешь 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
Вы можете использовать битовые поля для этого. Битовые поля — это специальные структуры, в которых вы можете указывать переменные в битах.
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
Прелесть битовых полей в том, что вам не нужно иметь дело с операторами сдвига и т. Д. Обозначение довольно простое. Как всегда, при работе с битами возникает проблема переносимости.
просто избавьтесь от 8 * в вашем коде.
int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)
int x = (number >> 3) & 0x1f;
даст вам целое число, где последние 5 бит являются 8-4 битами number
и нули в других битах.
Так же,
int y = number & 0x7;
даст вам целое число с последними 3 битами, установите последние 3 бита number
и нули в остальном.