【问题标题】:Bit-wise operations to implement logical shift to the right [duplicate]实现逻辑右移的按位运算[重复]
【发布时间】:2014-09-21 23:09:39
【问题描述】:

所以我正在尝试解决这个家庭作业,但我已经被这个特殊问题困扰了几个小时,无法弄清楚。我觉得我很亲近!但是后来我更改了代码中的某些内容,而其他内容不正确..

/*
 * logicalShift - shift x to the right by n, using a logical shift
 *   Can assume that 0 <= n <= 31
 *   Examples: logicalShift(0x87654321,4) = 0x08765432
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3
 */
int logicalShift(int x, int n) {

    int move;
    int y;
    y = x >> n;
    y = ~y << 1;
    move = (y & (x >> n));

    return move;
}

这里缺少什么?我得到 0x80000000 &gt;&gt; 31 为 0 但应该是 1 - 但除此之外我不知道..

【问题讨论】:

标签: c bit-manipulation bitwise-operators integer-arithmetic


【解决方案1】:

0x80000000 >> 31 = 1 如果是逻辑移位。

0x80000000 >> 31 = -1 如果是算术移位。

在 C++ 中,如果被移位的值是无符号的,则为逻辑移位。

在 Java 中,&gt;&gt; 是算术移位。 &gt;&gt;&gt; 是逻辑移位。

【讨论】:

  • 0x80000000 如果使用逻辑移位 31 移位,则应为 1。
  • 是的。抱歉.. 计算错误。
  • C 中的右移是implementation defined,因此您不能依赖无符号类型在所有平台上进行逻辑移位
【解决方案2】:

C 的&gt;&gt; 运算符已经对无符号整数执行了逻辑右移。这符合您的要求吗?

#include <stdio.h>

unsigned long int logicalShift(unsigned long int x, unsigned int n) {
  return x >> n;
}

int main() {
  unsigned long int value = 0x80000000UL;
  unsigned int shift_amt = 31;
  unsigned long int result = logicalShift(value, shift_amt);
  printf("0x%lx >> %d = 0x%lx\n", value, shift_amt, result);
  return 0;
}

结果:

0x80000000 >> 31 = 0x1

如果不允许转换为无符号数据类型,则根据引用 K&R 第二版的this answer by Ronnie,在 C 中右移有符号值的结果是实现定义的。即使this possible homework assignment 被修改为允许除法运算符,涉及对`x / (1 the rounding for division involving a negative number is also implementation-defined prior to C99。因此,除非您能告诉我们您的讲师正在使用哪种 C 实现以及它实现了哪种 ABI,否则这个问题似乎没有既简单又可移植的答案。

【讨论】:

  • 我不允许更改数据类型:/
  • @drleifz:那很不方便。你还有什么不被允许做的?可以使用演员表吗?
  • 我只能使用按位运算符 (! ~ & ^ | + >) 。不允许使用强制转换、if 语句、函数或类似的东西 :)
  • 您已经使用了不在您允许的运算符列表中的赋值 (=)。可能需要查看这些要求并确保您走在正确的轨道上。
  • = 根据老师的说法,不被视为按位运算符。但是我可以使用上面的那些按位运算符,包括(=)但不包括(-、&&、||、if 语句、函数)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多