Как разбить беззнаковое длинное int (32 бита) на 8 полубайтов?

Прошу прощения, если мой вопрос сбивает с толку, но вот пример того, что я хочу сделать.

скажем, у меня есть unsigned long int = 1265985549 в двоичном формате, я могу записать это как 01001011011101010110100000001101

теперь я хочу разбить это двоичное 32-битное число на 4 бита, как это, и работать отдельно с этими 4 битами

0100 1011 0111 0101 0110 1000 0000 1101

любая помощь будет оценена.


person Astronautilus    schedule 07.05.2014    source источник
comment
решение C ++ заключалось бы в использовании std::bitset, а затем смещении и маскировке полубайтов.   -  person tillaert    schedule 07.05.2014
comment
Не могли бы вы уточнить, что вы хотите делать с закусками? Обычно при манипуляции с битами нет необходимости разбивать вещи на поля, они уже неявно разделены на отдельные биты - просто не делайте ничего, что могло бы передавать информацию из одного поля в другое.   -  person harold    schedule 07.05.2014
comment
Я проверяю количество единиц в одном полубайте, а затем, если он нечетный, я добавляю 1 к своей переменной или, если он четный, я добавляю 0 и формирую еще одно 8-битное число.   -  person Astronautilus    schedule 07.05.2014
comment
@Astronautilus хорошо, это пример случая, когда вам на самом деле не нужно извлекать полубайты   -  person harold    schedule 07.05.2014


Ответы (3)


Вы можете получить 4-битный полубайт в позиции k, используя битовые операции, например:

uint32_t nibble(uint32_t val, int k) {
    return (val >> (4*k)) & 0x0F;
}

Теперь вы можете получить отдельные полоски в цикле, например:

uint32_t val = 1265985549;
for (int k = 0; k != 8 ; k++) {
    uint32_t n = nibble(val, k);
    cout << n << endl;
}

Демонстрация на ideone.

person Sergey Kalinichenko    schedule 07.05.2014
comment
@ Jarod42: Я бы сказал std::uint32_t val. Это единственный способ убедиться. - person Mike Seymour; 07.05.2014
comment
просто дополняя, OP может распечатать полубайты в двоичном формате (похоже, что и нужно), используя #include <bitset> и cout << bitset<4>(n) << endl - person Massa; 07.05.2014
comment
Ваши клевки были перевернуты ...: D - person Massa; 07.05.2014

short nibble0 = (i >>  0) & 15;
short nibble1 = (i >>  4) & 15;
short nibble2 = (i >>  8) & 15;
short nibble3 = (i >> 12) & 15;

и т.д

person sp2danny    schedule 07.05.2014
comment
Я бы предпочел использовать 0x0F, чтобы более подробно рассказать о битовой маскировке. - person Jarod42; 07.05.2014

Основываясь на комментарии, объясняющем фактическое использование этого, вот другой способ подсчитать, сколько полубайтов имеют нечетную четность: (не проверено)

; compute parities of nibbles
x ^= x >> 2;
x ^= x >> 1;
x &= 0x11111111;
; add the parities
x = (x + (x >> 4)) & 0x0F0F0F0F;
int count = x * 0x01010101 >> 24;

Первая часть - это просто обычный тип вычисления четности «xor all the bit» (где «all bit» относится ко всем битам в полубайте, а не во всем целочисленном), вторая часть основана на этот алгоритм подсчета битов, пропуская некоторые шаги, которые не нужны, потому что некоторые биты всегда равны нулю и поэтому не должны быть добавлены.

person harold    schedule 07.05.2014