问题:《C语言程序设计》的第2-8个练习中,“编写一个函数rightrot(x,n),将整数x向右旋转n个位置并返回值。”我已经用我所知道的所有方法做了这个练习。 这里是我遇到的问题。以29为例,将其向右旋转一位。11101变成11110或30。假设我们正在使用无符号整数类型大小为32位的系统。更进一步地说,我们在无符号整数变量中存储数字29。在内存中,数字前面有27个零。因此,当我们使用以下算法之一将29向右旋转一位时,我们得到的数字是2147483662。这显然不是期望的结果。
这个解决方案给出了我期望的答案30,但如果你用像31(11111)这样的数字来代替x,会有问题,具体来说,当n为1时结果是47。我之前没有考虑到这一点,但如果使用8(1000)这样的数字,则会出现混乱。8中只有一个设置的位,因此移位肯定会出错。我目前的理论是前两个解决方案是正确的(大部分),我只是漏掉了什么...
unsigned int rightrot(unsigned x, int n) {
return (x >> n) | (x << (sizeof(x) * CHAR_BIT) - n);
}
从技术上讲,这是正确的,但我认为在11101前面的27个零是无关紧要的。我还尝试了其他几种解决方案:
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,但如果你用像31(11111)这样的数字来代替x,会有问题,具体来说,当n为1时结果是47。我之前没有考虑到这一点,但如果使用8(1000)这样的数字,则会出现混乱。8中只有一个设置的位,因此移位肯定会出错。我目前的理论是前两个解决方案是正确的(大部分),我只是漏掉了什么...