【C程序设计语言第二版】练习2-8:将x循环右移n位

解题思路

我们可以用一个变量rbit来记录x最右边的位移到最左端的位置(len(x) - 1),然后我们把x右移一位,再对右移后的x与rbit进行或操作,这就完成了一次对x的循环右移操作,我们操作n次即可完成。

//计算出运行程序的计算机所使用的字长
int wordlength()
{
    int i;
    unsigned v = (unsigned) ~0;
    for(int i = 1; (v = v >> 1) > 0; ++i);
    return i;
}

unsigned rightrot(unsigned x, int n)
{
    int len = wordlength();
    int rbit;
    while(n-- > 0) {
        rbit = (x & 1) << (len - 1);
        x = x >> 1;
        x = x | bit;
    }
    return x;
}

优化解法

如果对x进行循环右移的总位数n与一个无符号整数的二进制位数(即这台计算机的字长)相等,完成这些次循环右移后的结果将于x完全一样,因此我们就不必对x进行循环右移了。如果n小于这台计算机的字长,那我们就必须把x循环右移n位,如果n大于这台计算机的字长,那么我们只需利用取模运算求出n对这台计算机字长的余数,再把x循环右移这个余数所代表的次数。基于上述分析,我们得出了一个无需使用循环语句的解决方案。
~0 << n:把一个全1的屏蔽码左移n为,在它最右端制造n位0。
~(~0 << n) : 把这个屏蔽码最右端的n位设置为1,其余位设置为0。

当我们用这个屏蔽码和x进行与运算是,x的最右端n位将被赋值给变量rbits,然后将rbits中的1左移到它的最左端,把x右移n位,再对右移后的x和rbits进行或运算就完成了。

unsigned rightrot(unsigned x, int n)
{
    int len = wordlength();
    unsigned rbits;
    if((n == n % len) > 0) {
        rbits = ~(~0 << n) & x;
        rbits = rbits << (len - n);
        x = x >> n;
        x = x | rbits;
    }
    return x;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值