Проблема: Упражнение 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 установлен только один бит, поэтому сдвиг наверняка будет неправильным. Моя теория на данный момент заключается в том, что первые два решения верны (в основном), и я просто что-то упускаю ...