2.8 编写一个函数rightrot(x, n),该函数返回将x循环右移(即从最右端移出的位将从最左端再移入)n(二进制)位后所得到的值。

来源:互联网 发布:蒙古掠夺欧洲女子知乎 编辑:程序博客网 时间:2024/05/29 13:53

Answer Book 

第一种解法 是 每次将x最右端右移1位 与 该位移到最左端  进行或运算 ,这样进行n次循环即可。

源程序:

  /*rightrot: rotate x to the right by n position*/unsigned rightrot(unsigned x, int n){ int wordlength(void); int rbit;              /* rightmost bit*/ while(n-- > 0) {  rbit = (x & 1) << (wordlength() - 1);  x = x >> 1;     x = x | rbit;  }}


/* 计算出运行程序的计算机所使用的字长 */

int wordlength(void)     { int i; unsigned v = (unsigned) ~0;     for(i = 1; (v = v >> 1) > 0; ++i)  ; return i;}


2.第二种解法

/*
   如果对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位
*/
int wordlength(void)     { int i; unsigned v = (unsigned) ~0;     for(i = 1; (v = v >> 1) > 0; ++i)  ; return i;}

 

3. 这种方法 比较简练

判断 x 中最右端位是1还是0,是1就进行运算,若是0 ,直接右移即可。

unsigned rightrot(unsigned x, unsigned n){    while (n > 0)  {      if ((x & 1) == 1)  //如果最右端位为 1         x = (x >> 1) | ~(~0U >> 1);  //  ~(~0 >> n)将最高n位 置1     else          x = (x >> 1);      n--; }       return x;}



4.
unsigned int rightrot(unsigned int x, unsigned int n){        /* calculate number of bits in type */           size_t s = sizeof(x) * CHAR_BIT;           size_t p;        /* limit shift to range 0 - (s - 1) */            if  (n < s)                 p = n;           else                 p = n % s;         /* if either is zero then the original value is unchanged */           if((0 == x) || (0 == p))               return x;          return (x >> p) | (x << (s - p));}


原创粉丝点击