Битовые операции: Напишите функцию setbits (x, p, n, y), возвращающую значение x - C (СИ)
Формулировка задачи:
Пытаюсь освоить Си по книге Брайана Кернигана и Денниса Ритчи "Язык программирования Си".
Ну и по ходу выполняю упражнения. И вот есть там такое:
Функцию написал. Проверил - работает, как надо. Но меня смущает, что она какая-то не лаконичная что-ли. У них там так всё ловко и коротко получается. Я вот думаю: может я не Си-шно мыслю? Как считаете можно это по другому написать компактнее как-то что ли. Если есть у кого-то варианты, буду благодарен.
Упражнение 2.6.
Напишите функцию setbits(x, p, n, y), возвращающую значение x, в котором n битов, начиная с p-й позиции, заменены на n правых разрядов из y (остальные биты не изменяются).unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y)
{
unsigned int b1 = 1;
unsigned int b2 = 0;
for (n; n > 0; --n)
{ b2 = b2 | b1;
b1 = b1 << 1; } /* ставим n битов справа в q */
b1 = b2; /* копию в b1 */
b1 = b1 << p; /* сдвигаем установленные биты на p -ю позицию */
b1 = ~b1; /* инвертируем */
x = x & b1; /* вырезаем "дырку" в x в месте куда надо вставить из y */
b2 = b2 & y; /* берём n битов из правой части y */
b2 = b2 << p; /* сдвигаем их на p позицию */
x = x | b2; /* устанавливаем их в x */
return x;
}
В коментарии ошибка.
Ставим n битов справа в b2 - так правильно.
Решение задачи: «Битовые операции: Напишите функцию setbits (x, p, n, y), возвращающую значение x»
textual
Листинг программы
#include <stdio.h>
unsigned setbits (unsigned x, int p, int n, unsigned y);
int main()
{
unsigned x = 61455; //1111 0000 0000 1111
unsigned y = 23247; //0101 1010 1100 1111
int p = 6;
int n = 4;
printf("%u\n", setbits(x,p,n,y)); //жду ответ 1111 0011 1100 1111
return 0;
}
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
x = (x | ((y<<p)&(~(~0<<(p+n)))));
return x;
}
Объяснение кода листинга программы
В данном коде реализована функция setbits, которая принимает четыре аргумента:
- x - исходное число, в котором необходимо установить биты.
- p - позиция, начиная с которой необходимо установить биты.
- n - количество битов, которые необходимо установить.
- y - число, биты которого необходимо установить в x.
Для выполнения этой задачи используется битовая операция
OR(логическое ИЛИ), которая объединяет два числа в одно, сохраняя все установленные биты из обоих чисел. Выполнение функции setbits в данном коде можно описать следующим образом: - Входные числа x, p, n, y заданы в коде.
- В функции setbits происходит вычисление нового значения x с помощью следующего выражения:
x = (x | ((y<<p)&(~(~0<<(p+n)))));
Здесь:
— x - исходное число, в котором необходимо установить биты.
— y - число, биты которого необходимо установить в x.
— p - позиция, начиная с которой необходимо установить биты.
— n - количество битов, которые необходимо установить.
— (~0<<(p+n)) - выражение, которое сдвигает число 0 влево на (p+n) позиций, а затем инвертирует его. Это позволяет получить число, в котором все биты, начиная с позиции p+n, установлены в 1.
— (y<<p)&(~(~0<<(p+n)))) - выражение, которое сдвигает число y влево на p позиций, а затем с помощью оператора
ANDобъединяет его с числом, полученным из выражения (~0<<(p+n)). Это позволяет установить в x только те биты, которые соответствуют установленным битам числа y, начиная с позиции p. — x | ((y<<p)&(~(~0<<(p+n)))) - объединение чисел x и ((y<<p)&(~(~0<<(p+n)))) с помощью оператораOR. Результатом является новое значение x, в котором установлены необходимые биты. - Новое значение x возвращается из функции setbits и выводится на экран с помощью функции printf. Таким образом, результатом выполнения данного кода будет число 1111 0011 1100 1111, которое выводится на экран.