2013-09-24 153 views
4
int mystery(int x, int n) 
{ 
    return (x + (x>>31 & ((1 << n) + ~0))) >> n; 
} 

我一直在想出这个代码是如何工作的。这是我到目前为止有:这段代码做了什么?

  • 转移N个左超过一个,
  • 补充说,结果1^32(?为什么)
  • ANDS这个结果与x转移到31(不会这只是清除x的值>> 31?)
  • 并将其移入由n个权之前,增加了X(再次,我不明白为什么)
+2

看看x和n变量的类型是什么可能很有趣。 – SirDarius

+0

x和n如何定义? 32b或64b? – Leeor

+1

如果'x'是一个'int32',那么'x >> 31'在数字为负数时返回'1',如果数字为0则返回'0'或为正数。 – SJuan76

回答

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来适当地调整结果。

请注意严格地说,表达式依赖于特定于实现的行为,因为它假定right shifti一个有符号整数保留符号位。虽然大多数编译器和平台都是如此,但无法保证,所以表达式不是100%安全或便携的。

还要注意,表达式有一个硬编码假设,即int为32位,这也使得它不可移植。与任何int大小一起使用的更便携版本将是:

return (x + (x >> (sizeof(int) * CHAR_BIT - 1) & ((1 << n) + ~0))) >> n; 
+1

我试过了,我得到0..Never想'x <0'..Nice ans ... + 1 – Anirudha

+0

OP说变量的返回类型和类型是'int'。在int为64位的环境中,它的工作原理是否相同? – SirDarius

+0

否 - 它假定32位整数(即int32_t)。然而,使其更加通用并不难 - 我用更便携的版本更新了答案。 –