int mystery(int x, int n)
{
return (x + (x>>31 & ((1 << n) + ~0))) >> n;
}
我一直在试图弄清楚这段代码是如何工作的。这是我到目前为止所拥有的:
- 将 n 左移 1,
- 将该结果添加到 1^32(为什么?)
- 并且这个结果到 x 转移到 31 (这不只是清除 x>>31 的值吗?)
- 在它移动 n 之前,添加 x(再次,我不明白为什么)
int mystery(int x, int n)
{
return (x + (x>>31 & ((1 << n) + ~0))) >> n;
}
我一直在试图弄清楚这段代码是如何工作的。这是我到目前为止所拥有的:
它除以 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;