Вращение битов в C

Проблема: Упражнение 2-8 языка программирования C: «Напишите функцию rightrot (x, n), которая возвращает значение целого числа x, повернутого вправо на n позиций».

Я сделал это все, что я знаю. Вот проблема, с которой я столкнулся. Возьмите заданное число для этого упражнения, скажем 29, и поверните его вправо на одну позицию.
11101, и оно становится 11110 или 30. Допустим, ради аргумента, что система, над которой мы работаем, имеет размер беззнакового целочисленного типа 32 бита. Далее предположим, что у нас есть число 29, хранящееся в целочисленной переменной без знака. В памяти перед числом будет 27 нулей. Итак, когда мы поворачиваем 29 вправо, используя один из нескольких алгоритмов, которые я опубликовал ниже, мы получаем число 2147483662. Это явно не желаемый результат.

unsigned int rightrot(unsigned x, int n) {
    return (x >> n) | (x << (sizeof(x) * CHAR_BIT) - n);
}

Технически это правильно, но я думал, что 27 нулей перед 11101 были незначительными. Я также пробовал несколько других решений:

int wordsize(void) {    // compute the wordsize on a given machine...
    unsigned x = ~0;
    int b;
    for(b = 0; x; b++)
        x &= x-1;
    return x;
}

unsigned int rightrot(unsigned x, int n) {
    unsigned rbit;
    while(n --) {
        rbit = x >> 1;
        x |= (rbit << wordsize() - 1);
    }
    return x;

Это последнее и окончательное решение - то, где я думал, что оно у меня есть, я объясню, где оно не удалось, как только дойду до конца. Я уверен, что вы увидите мою ошибку ...

int bitcount(unsigned x) {
    int b;
    for(b = 0; x; b++)
        x &= x-1;
    return b;
}

unsigned int rightrot(unsigned x, int n) {
    unsigned rbit;
    int shift = bitcount(x);
    while(n--) {
        rbit = x & 1;
        x >>= 1;
        x |= (rbit << shift);
    }
}

Это решение дает ожидаемый ответ 30, который я искал, но если вы используете число для x, например, о, скажем, 31 (11111), тогда возникнут проблемы, конкретно результат - 47, используя один для n. Я не думал об этом раньше, но если использовать число вроде 8 (1000), то беспредел. В 8 установлен только один бит, поэтому сдвиг наверняка будет неправильным. Моя теория на данный момент заключается в том, что первые два решения верны (в основном), и я просто что-то упускаю ...

6
задан Bill the Lizard 6 December 2012 в 18:12
поделиться