Операции, с которыми вам нужно ознакомиться, - это маска и смещение. Не используйте pow
для битовой перестановки. Это большая, тяжеловесная функция, предназначенная для численных расчетов.
Есть несколько способов сгенерировать шаблон _ _ 0 _ 1 0 0 _ 0 0 0 1
, который вы ищете. Один из них - сначала очистить крайнее правое пространство. Если x
содержит исходное значение 0100001
, то первым шагом является маскировка всех, кроме последних 4 битов. Это x & 0xfu
. &
- это логическое «и». Все остальные биты можно скрыть с помощью x & ~0xfu
. ~
поразрядно "нет". Теперь вы хотите сдвинуть эти другие биты влево на одно место и объединить их с младшими 4 битами, используя «или». Итак, всего у нас есть:
unsigned x = 'A';
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
Чтобы переместить самый верхний бит 1 влево, выполните ту же процедуру, только теперь вы хотите, чтобы самые правые 8 биты остались на своем месте,в то время как 9-й и выше сдвигаются влево. Вам нужна маска 0xffu
. Таким образом, мы получаем
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
Теперь вы можете "или" в битах четности и затем распечатать побитовое представление с чем-то вроде:
for (unsigned m = 0x800; m; m >>= 1) printf("%d", (m & result) != 0);
Опять 0x800
маска для бита 11. Вы используете ее для проверки бита 11 результата с помощью (m & result) != 0
. Он имеет значение 1, если установлен соответствующий бит result
, иначе 0, именно то, что вы хотите напечатать. Каждая последующая итерация цикла for
смещает маску на одно место вправо. Цикл останавливается, когда бит полностью сдвинут. Это происходит после 12 итераций, поэтому вы печатаете 12 бит, что, по-видимому, вам и нужно.
Примечание. Повсюду я использовал типы без знака. Здесь это не является строго необходимым, но обычно менее подвержено ошибкам использование неподписанных типов для битовых операций, поскольку расширение знака может привести к неожиданным результатам.
В общем, вы можете проверить это с 0xff
каквход, чтобы увидеть «дыры», где принадлежат биты четности:
#include <stdio.h>
int main(void)
{
unsigned x = 0xffu;
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
for (unsigned m = 0x800; m; m >>= 1)
printf("%d", (m & result) != 0);
return 0;
}
Это печатает 001011101111
, как вы ожидаете и ожидаете.
Есть много интересных деталей для работывне. Я дам это тебе.