为什么这可以用于确定数字是2的幂?

时间:2017-01-31 20:41:08

标签: bit-manipulation

int isPower2(int x) {
    int neg_one = ~0;
    return !(neg_one ^ (~x+1));
}

这段代码有效,我已经实现了它并且表现完美。但是,我无法理解为什么。当我手工完成时,它对我没有任何意义。

假设我们以4位数字开头,4:

0100

这显然是2的幂。但是当我遵循算法时,~x + 1 =

1011 + 1 = 1100

对负数(11​​11)进行异或运算得到0011.!(0011)= 0.我在哪里错了?我知道这必须是我手工做的方式的一个缺陷。

1 个答案:

答案 0 :(得分:0)

用Inigo Montoya的话来说,“我认为这不符合你的想法。”

让我们把它分解。

  1. ~x + 1
  2. 这会翻转'x'的位,然后加一。这与采用'x'的2的补码相同。或者,换句话说,这与'-x'相同。

    1. neg_one ^(~x + 1)
    2. 使用我们在步骤1中提到的内容,这简化为......

      neg_one ^ (-x)
      

      或更简单......

      -1 ^ (-x)
      

      但是等等!对-1进行XOR'ing与翻转位相同。那是......

      ~(-x)
      
      1. 〜(-x)
      2. 如果我们使用2的补码,这可以更简化。

        ~(-x) + 0
        = ~(-x) + 1 - 1
        = x - 1
        

        如果您正在寻找一种简单的方法来确定数字是否为2的幂,则可以使用以下代码来代替大于零的数字。如果它是2的幂,它将返回true。

        (x & (x - 1)) == 0