Функция инвертирования K&R C

Упражнение 2-7. Напишите функцию invert(x,p,n), которая возвращает x с инвертированными n битами, начинающимися с позиции p (т. е. 1 превращается в 0 и наоборот), оставляя остальные без изменений.

#include <cstdio>

int invert(unsigned int x, int p, int n)
{
    int inverted_x = ~x;
    //gets rid of bits before position p
    inverted_x = inverted_x << (p - 1);
    inverted_x = inverted_x >> (p - 1);

    //gets rids of bits after position p+n
    inverted_x = inverted_x >> ((sizeof(x) * 8) - (p + n));
    inverted_x = inverted_x << ((sizeof(x) * 8) - (p + n));
    return inverted_x;

}

int main()
{
    int a = 123;
    printf("%d \n", invert(a, 2, 3));
}

Что я делаю неправильно?


person Tommy Saechao    schedule 05.12.2015    source источник
comment
Возможный дубликат функции инвертирования битов в упражнении K&R 2-7   -  person ashiquzzaman33    schedule 05.12.2015


Ответы (1)


На мой взгляд, намного проще написать функцию следующим образом. Я предполагаю, что позиция начинается с 0.

int invert( int x, int p, int n )
{
    unsigned int mask = ~( ~0 << n ) << p;

    return x ^ mask;;
}    

Что касается вашей функции, то хотя бы эти утверждения

//gets rid of bits before position p
inverted_x = inverted_x << (p - 1);
inverted_x = inverted_x >> (p - 1);

уже ошибаются. Они не делают то, что вы думаете.

Правильно было бы написать

//gets rid of bits before position p
inverted_x = inverted_x >> p;
inverted_x = inverted_x << p;

Тем не менее, выполнять эту операцию не имеет смысла, так как теряются младшие биты исходного числа.

person Vlad from Moscow    schedule 05.12.2015