Напишите функцию setbits(x, p, n, y), возвращающую значение x, в котором n битов, начиная с p-й позиции, заменены на n правых разрядов из y (остальные биты не изменяются).
#include <stdio.h>
unsigned setbits(unsigned x, int p, int n, unsigned y);
int main(void)
{
printf("%u\n", setbits(126, 4, 3, 57));
return 0;
}
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
/* Обнуление поля для замены: xxxxx00000xxxxx */
unsigned a = x & ~(~(~0U << n) << (p + 1 - n));
/* Подготовка битового поля для замены: 00000yyyyy00000 */
unsigned b = (y & ~(~0U << n)) << (p + 1 - n);
/* Вычисляем итоговое значение: xxxxxyyyyyxxxxx */
return a | b;
}
В качестве результата мы должны получить — 0110 0110, где синим цветом выделены разряды x, а красным — y.
126(10) = 0111 1110(2)
Готовим число x = 126 к замене n = 3 разрядов начиная с p = 4 позиции:
Поле для замены обнулим, чтобы в результате получить 0110 0010(2)
0111 1110
&
1110 0011
---------
0110 0010
57(10) = 0011 1001(2)
Готовим n = 3 правых разряда числа y = 57 для замены:
Необходимо получить нули во всех разрядах, кроме тех на которые будет проводится замена на определенных позициях 0110 0110(2)
Для нахождения искомого значения выполняем операцию побитового ИЛИ для установки единицы в тех разрядах a, которым соответствуют единицы b:
#include <stdio.h>
unsigned setbits(unsigned x, int p, int n, unsigned y);
int main(void)
{
printf("%u\n", setbits(126, 4, 3, 57));
return 0;
}
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
/* Обнуление поля для замены: xxxxx00000xxxxx */
unsigned a = x & ~(~(~0U << n) << (p + 1 - n));
/* Подготовка битового поля для замены: 00000yyyyy00000 */
unsigned b = (y & ~(~0U << n)) << (p + 1 - n);
/* Вычисляем итоговое значение: xxxxxyyyyyxxxxx */
return a | b;
}
В качестве результата мы должны получить — 0110 0110, где синим цветом выделены разряды x, а красным — y.
126(10) = 0111 1110(2)
Готовим число x = 126 к замене n = 3 разрядов начиная с p = 4 позиции:
Поле для замены обнулим, чтобы в результате получить 0110 0010(2)
- Константа 0U состоит из одних нулей — 0000 0000
- Константа ~0U состоит из одних единиц — 1111 1111
- Выполняем побитовый сдвиг константы ~0U влево на n = 3 разрядов — 1111 1000
- Выполняем побитовое отрицание — 0000 0111
- Выполняем побитовый сдвиг влево << на (p + 1 - n) = 2 разрядов, заполняя освобождающиеся биты нулями — 0001 1100
- Выполняем побитовое отрицание — 1110 0011
- Для обнуления необходимых разрядов числа x применяем побитовое И
0111 1110
&
1110 0011
---------
0110 0010
57(10) = 0011 1001(2)
Готовим n = 3 правых разряда числа y = 57 для замены:
Необходимо получить нули во всех разрядах, кроме тех на которые будет проводится замена на определенных позициях 0110 0110(2)
- Константа 0U состоит из одних нулей — 0000 0000
- Константа ~0U состоит из одних единиц — 1111 1111
- Выполняем побитовый сдвиг константы ~0U влево на n = 3 разрядов — 1111 1000
- Выполняем побитовое отрицание — 0000 0111
- Применяем побитовое И
&
0000 0111
---------
0000 0001
6. Выполняем побитовый сдвиг влево << на (p + 1 - n) = 2 разрядов, заполняя освобождающиеся биты нулями — 0000 0100
Для нахождения искомого значения выполняем операцию побитового ИЛИ для установки единицы в тех разрядах a, которым соответствуют единицы b:
0110 0010
|
0000 0100
---------
0110 0110
Комментариев нет:
Отправить комментарий