怎么用逻辑右移实现算术右移?

发布于 2022-09-02 12:53:58 字数 203 浏览 17 评论 0

怎么用逻辑右移实现算术右移?修改

用逻辑右移实现算术右移。
csapp第二章章末习题。
禁止使用条件,循环语句,禁止使用右移和取模运算。

int sar (int x, int k)
{
     int xsrl = (unsigned)x >> k;
     // 接下来怎么办?
     
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从﹋此江山别 2022-09-09 12:53:58
int sar (int x, int k)
{
    int xsrl = (unsigned) x >> k;
    
    int len = sizeof(int) * 8;
    
    int mask = 1 << (len - k - 1);
    
    return (xsrl ^ mask) - mask;
}
小傻瓜 2022-09-09 12:53:58

不是不给用右移么?怎么你代码又有。。

提示:

  • 右移一位约等价于除以2

  • 用递归代替循环

我爱人 2022-09-09 12:53:58

事实上这个题目是不允许强制类型转换/条件分支/循环的。。。
一切都只能通过位运算完成,另外使用的常数也不能超过255
就是说在写完答案后不能仅仅make btest + ./btest funcion_name,还应该用./dlc bits.c检测下是否合法。特别提一下dlc,这里作者非常用心的写了个parser检测是否合法。

logicalShift

  • 总体思路是将1左移31位然后右移n-1位从而计算出掩码,然后(x>>n)&mask即可得出答案
  • IA32下不能够偏移超过31位,会在cl寄存器中限定移动位数为0-31,也就是说移动32位不是置0,而是不移动
//  错误代码示例
int mask = 1 << 31 >> (n + (~1 + 1));
return (x>>n) & mask;
// n = 0时会出错
  • 使用一种另类的条件!!n,它会在n=0时返回0n!=0返回1,使用(!!n)&1的返回值,我们就相当于对两种情况做了下分类n==0?n=0:n=1;

答案

int logicalShift(int x, int n) {
  /**
   * can not shift more than 31 bits
   * mask computation:
   * (1) left shift 1 to the leftmost bit
   * (2) right shift the number in step in (1) for n-1 bits
   * since IA32 will rotate the shift number to 32
   * (which means we are able to shift 31 bits at most)
   * we cannot just implement it as above
   * ====
   * !!n act as a condition, when n=0 it returns 0, otherwise 1
   * so we shift (!!n) and solve the IA32 feature
   * ====
   * here is the wrong code:
   * mask = 1 << 31 >> (n + (~1 + 1));
   * when n = 0, it will not shift at all
   */
  return (x>>n)&(~(((!!n) & 1)<<31>>(n+(~1+1))));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文