我目前正在使用The C Programming Language(K& R)[练习2.8]进行练习,以编写一个正确的循环移位函数来旋转整数x,n个位置。
我相信我已经提出了一个解决方案,但出于一些奇怪的原因,当我超出单词长度时(即100位移位),当我相信我不应该这样做时,我仍然会得到正确的答案。 ; t代码如下。
#include <stdio.h>
unsigned rightrot(unsigned x, int n);
int main(void)
{
printf("%u\n", rightrot(1,100)); /* this should yield zero (overshift) */
return 0;
}
unsigned rightrot(unsigned int x, int n)
{
unsigned a = ~0;
int i;
for (i = 1; a > 1; ++i) /* calculating the word length */
a = a/2;
return (x >> n) | (x << (i-n));
}
线上的变化:
return (x >> n) | (x << (i-n));
应该在离开0 | 0
时将所有二进制数字移出我认为,当传递的移位大小大于字长时。但令我惊讶的是,这段代码返回的答案完全相同,就好像我使用的是允许大于字长的n的以下版本:
return (x >> (n % i)) | (x << ((i-n) % i);
记住i
是单词长度。
我正在使用带有-std = c89和-pedantic-errors的gcc 4.7.2,并且也没有得到任何警告。
答案 0 :(得分:3)
在UNDEFINED中移动超过C中的单词大小,所以任何事情都可能发生。在大多数机器上,使用具有log 2 字大小选择位的多路复用树完成移位,忽略移位计数的较高位,因此在32位机器上移位100可能是与4的班次相同。但你可能得到任何东西,包括崩溃。
答案 1 :(得分:3)
如果n
大于i
,则i - n
为否定。使用带有负数的<<
运算符作为右操作数是未定义的行为。