4
int mystery(int x, int n)
{
   return (x + (x>>31 & ((1 << n) + ~0))) >> n;
}

我一直在试图弄清楚这段代码是如何工作的。这是我到目前为止所拥有的:

  • 将 n 左移 1,
  • 将该结果添加到 1^32(为什么?)
  • 并且这个结果到 x 转移到 31 (这不只是清除 x>>31 的值吗?)
  • 在它移动 n 之前,添加 x(再次,我不明白为什么)
4

1 回答 1

11

它除以 2^n 并正确舍入(向零舍入),因此表达式等效于:

y = x / (1 << n);

如果您对除以 2^n 采取天真的方法,即

y = x >> n;

对于 x < 0,您会得到不正确的舍入。

这部分表达式:(x>>31 & ((1 << n) + ~0))对于 x >= 0 等于零,但对于 x < 0 它通过添加 2^n - 1 来适当地调整结果。

请注意,严格来说,表达式依赖于特定于实现的行为,因为它假定右移有符号整数会保留符号位。虽然对于大多数编译器和平台都是如此,但不能保证,因此表达式不是 100% 安全或可移植的。

另请注意,该表达式有一个硬编码假设,即 int 是 32 位,这也使其不可移植。适用于任何大小的 int 的更便携的版本是:

   return (x + (x >> (sizeof(int) * CHAR_BIT - 1) & ((1 << n) + ~0))) >> n;
于 2013-09-24T14:54:11.463 回答