C中的循环移位,意外行为
我目前正在做一个C编程语言(K&R)[练习2.8]的练习,写一个右循环移位函数来旋转整数x,n个位置 我相信我已经想出了一个解决方案,但出于某种奇怪的原因,当我移动超过单词长度(即100位移动)时,我仍然得到了正确的答案,而我认为我不应该使用下面的代码C中的循环移位,意外行为,c,bit-shift,kernighan-and-ritchie,C,Bit Shift,Kernighan And Ritchie,我目前正在做一个C编程语言(K&R)[练习2.8]的练习,写一个右循环移位函数来旋转整数x,n个位置 我相信我已经想出了一个解决方案,但出于某种奇怪的原因,当我移动超过单词长度(即100位移动)时,我仍然得到了正确的答案,而我认为我不应该使用下面的代码 #include <stdio.h> unsigned rightrot(unsigned x, int n); int main(void) { printf("%u\n", rightrot(1,100)); /*
#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));
}
记住i
是单词长度
我正在使用GCC4.7.2,带有-std=c89和-pedantic错误,并且也没有收到任何警告。在未定义的情况下,移动的字号超过了C中的字号,因此可能会发生任何情况。在大多数机器上,移位是通过带有log2wordsize选择位的mux树完成的,而不考虑移位计数的高位,因此32位机器上100的移位可能与4的移位相同。但是您可能会得到任何结果,包括崩溃。在未定义的情况下,移动的字号超过了C中的字号,因此任何事情都可能发生。在大多数机器上,移位是通过带有log2wordsize选择位的mux树完成的,而不考虑移位计数的高位,因此32位机器上100的移位可能与4的移位相同。但是你可能得到任何东西,包括崩溃。如果
n
大于i
,那么i-n
为负。使用如果n
大于i
,则i-n
为负值。使用有趣的历史位:当80x86没有桶/漏斗移位器时,将16位int向左或向右移位超过16位会得到所有零值或all-1值(取决于移位的符号)。当他们添加快速移位硬件,使其不必使用微码循环时,它开始移位mod word-size。有趣的历史位:回到80x86没有桶形/漏斗形移位器时,将16位整数向左或向右移位超过16位会得到所有零或all-1值(取决于移位的符号)。当他们添加快移硬件,使其不必使用微码循环时,它开始移动mod字大小。我想这可能是我应该做的:return(x>(n%I))|(x我想这可能是我应该做的:return(x>(n%I))|(x
return (x >> n) | (x << (i-n));
return (x >> (n % i)) | (x << ((i-n) % i);