C语言 仅使用位操作,返回标记最高有效1位位置的掩码,如果x == 0,则返回0

pftdvrlh  于 2023-01-29  发布在  其他
关注(0)|答案(1)|浏览(114)

作为我的编程课--C语言入门的一部分,我正在写一个关于受限条件下的位操作的编码项目,尤其是在这个问题上,我陷入了困境,因为我不知道如何修正我的错误。

/* 
 * SigBitMask - return a mask that marks the position of the
 *           most significant 1 bit. If x == 0, return 0
 *   Example: SigBitMask(96) = 0x40
 *   Legal operations: ! ~ & ^ | + << >>
 *   Max operations: 16
 *   Rating: 4 
 */

除了上面列出的合法操作之外,我不能使用任何语句,比如do、if、while或else。我也不允许强制转换为其他数据类型。这包括使用unsigned。此外,我不能使用任何大于0xFF的常量,这对于这个问题来说非常重要,因为我不允许使用0x80000000。另外,假设我们使用的是32位机器。
这里的一个大问题是,我
不能
使用像-或 * 这样的操作,这将使这一点容易得多。
下面是我的代码:

int SigBitMask(int x) {
  x |= x >> 1;
  x |= x >> 2;
  x |= x >> 4;
  x |= x >> 8;
  x |= x >> 16;
  x = x ^ (x >> 1);
  return x & ~(x >> 1);
}

检查软件给我的错误是:

"ERROR: Test SigBitMask(-2147483648[0x80000000]) failed...
    ...Gives 0[0x0]. Should be -2147483648[0x80000000]

我不知道该如何着手解决我的问题。我更喜欢的不仅仅是答案。有人能解释一下这个过程吗?这个项目的全部意义就是学习用C语言编码。谢谢:)
编辑:我知道堆栈溢出已经有类似的问题,但他们的限制与我的不同,加上我正在寻找帮助修复我的代码,并了解原因。
编辑2:阐明了最大和合法操作的含义

ljsrvy3e

ljsrvy3e1#

去掉最后一行,因为它什么也没做,所以你的函数变成:

int SigBitMask(int x) {
  x |= x >> 1;
  x |= x >> 2;
  x |= x >> 4;
  x |= x >> 8;
  x |= x >> 16;
  return x ^ (x >> 1);
}

这对于非负输入非常有效,但是对于负输入,当最后一行运行时x将为-1,所以最后一行将给予0的结果,但是这是不好的,因为我们想要为所有负输入返回-2147483648(即0x 80000000)。
如果我们可以修补return表达式,通过使用|将其与另一个表达式组合,当x为-1时为0x 80000000,当x为非负时为0,会怎么样?(对于x的其他负值,我们不关心它的值。)你能想出这样的表达式吗?我能想出一个只使用3个运算符的表达式,但它包含了一些未定义的行为。

相关问题