Упражнение 2-7 из Язык программирования C:
Напишите функцию
invert(x,p,n)
, которая возвращаетx
с битамиn
, которые начинаются с позицииp
, инвертированными (т. Е. 1 изменен на 0 и наоборот), оставив остальные без изменений.
Я понял вопрос так: у меня 182, что 101(101)10
в двоичном формате, часть в скобках должна быть инвертирована без изменения остальных. Возвращаемое значение должно быть 10101010
, то есть 170 в десятичной системе.
Вот моя попытка:
#include <stdio.h>
unsigned int getbits(unsigned int bitfield, int pos, int num);
unsigned int invert(unsigned int bitfield, int pos, int num);
int main(void)
{
printf("%d\n", invert(182, 4, 3));
return 0;
}
/* getbits: get num bits from position pos */
unsigned int getbits(unsigned int bitfield, int pos, int num)
{
return (bitfield >> (pos+1-n)) & ~(~0 << num);
}
/* invert: flip pos-num bits in bitfield */
unsigned int invert(unsigned int bitfield, int pos, int num)
{
unsigned int mask;
unsigned int bits = getbits(bitfield,pos,num);
mask = (bits << (num-1)) | ((~bits << (pos+1)) >> num);
return bitfield ^ mask;
}
Это кажется правильным (мне), но invert(182, 4, 3)
выводит 536870730
. getbits()
работает нормально (прям из книги). Я записал, что происходит в выражении, которое я присвоил y
:
(00000101 << 2) | ((~00000101 << 5) >> 3) -- 000000101 is the part being flipped: 101(101)10
00010100 | ((11111010 << 5) >> 3)
00010100 | (01000000 >> 3)
00010100 | 00001000
= 00011100
10110110 (182)
^ 00011100
----------
= 10101010 (170)
Должно быть правильно, но это не так. Я выяснил, что здесь что-то не так: ((~xpn << (p+1)) >> n)
. Не понимаю как.
Кроме того, я понятия не имею, насколько общий этот код. Моя первоочередная задача - заставить это дело работать. Помощь в этом вопросе тоже приветствуется.