69,382
社区成员
发帖
与我相关
我的任务
分享
/*
编写一个函数rightrot(x, n),该函数返回将x循环右移(即从
最右端移出的位将从最左端再移入)n(二进制)位后得到的值
*/
#include <stdio.h>
int wordlength();
unsigned rightrot(unsigned x, int n);
int main()
{
int x, n;
int a;
x = 32769;
n = 7;
a = rightrot(x, n);
printf("a = %d\n", a); // 33554688
return 0;
}
// 计算运行该程序的计算机字长
int wordlength()
{
int i;
unsigned v;
v = (unsigned)~0;
for (i = 1; (v=v>>1) > 0; ++i)
{
;
}
return i;
}
/*
如果对x进行循环右移的总位数(n)与一个无符号整数的二进制
位数(即这台计算机的字长)相等,完成这些次循环右移后的结
果将与x完全一样,因此我们就不必对x进行循环右移了。
如果n小于这台计算机的字长,那我们就必须把x循环右移n位。
如果n大于这台计算机的字长,那么,我们只需先(利用取模运
算符)求出n对这台计算机的字长的余数,再把x循环右移这个余
数所代表的次数。基于上述分析,我们将得到一个不需要使用循
环语句的解决方案。
~0 << n,把一个全1的屏蔽码左移n位,在它的最右端制造出n位0
~(~0 << n),把屏蔽码最右端的n位设置为1,其余位则设置为0
当我们用这个屏蔽码和x进行AND运算时,x最右端的n位将被赋值
给变量rbits。然后,将rbits中的1左移到它的最左端,把x右移
n位,再对右移后的x和rbits进行OR运算,就完成了对无符号整
数x循环右移n位
*/
unsigned rightrot(unsigned x, int n)
{
unsigned rbits;
if ((n=n%wordlength()) > 0)
{
rbits = x & ~(~0<<n);
rbits = rbits << (wordlength()-n);
x = x >> n;
x = x | rbits;
}
return x;
}
#include <stdio.h>
int main(void)
{
unsigned int a=-1;
int b=-1;
printf("%d %x\n",a,a);
a>>=1;
printf("%d %x\n",a,a);
printf("%d %x\n",b,b);
b>>=1;
printf("%d %x\n",b,b);
getchar();
return 0;
}
unsigned rightrot(unsigned x, int n){
__asm {
mov eax,x
ror eax,n
}
}