среда, 19 ноября 2014 г.

Упражнение 2.6.

Напишите функцию 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)


  1. Константа 0U состоит из одних нулей  0000 0000
  2. Константа ~0U состоит из одних единиц  1111 1111
  3. Выполняем побитовый сдвиг константы ~0U влево на n = 3 разрядов  1111 1000
  4. Выполняем побитовое отрицание  0000 0111
  5. Выполняем побитовый сдвиг влево << на (p + 1 - n) = 2 разрядов, заполняя освобождающиеся биты нулями — 0001 1100
  6. Выполняем побитовое отрицание  1110 0011
  7. Для обнуления необходимых разрядов числа x применяем побитовое И

0111 1110
&
1110 0011
---------
0110 0010

57(10) = 0011 1001(2)
Готовим n = 3 правых разряда числа y = 57 для замены:
Необходимо получить нули во всех разрядах, кроме тех на которые будет проводится замена на определенных позициях 0110 0110(2)
  1. Константа 0U состоит из одних нулей  0000 0000
  2. Константа ~0U состоит из одних единиц  1111 1111
  3. Выполняем побитовый сдвиг константы ~0U влево на n = 3 разрядов  1111 1000
  4. Выполняем побитовое отрицание  0000 0111
  5. Применяем побитовое И
0011 1001
&
0000 0111
---------
0000 0001

    6. Выполняем побитовый сдвиг влево << на (p + 1 - n) = 2 разрядов, заполняя                     освобождающиеся биты нулями — 0000 0100

Для нахождения искомого значения выполняем операцию побитового ИЛИ для установки единицы в тех разрядах a, которым соответствуют единицы b:

0110 0010
|
0000 0100
---------
0110 0110

Комментариев нет:

Отправить комментарий