这个按位运算如何检查2的幂?

时间:2009-06-27 20:44:00

标签: c math bit-manipulation

我正在看一些应该是微不足道的代码 - 但是我的数学在这里惨遭失败。

这是一个条件,使用以下内容检查数字是否为2的幂:

if((num != 1) && (num & (num - 1))) { /* make num pow of 2 */ }

我的问题是,在num和num - 1之间使用按位AND如何确定数字是否为2的幂?

8 个答案:

答案 0 :(得分:90)

2减1的任何幂都是1 :( 2 N - 1 = 111 .... b < / em>的)

2 = 2^1.  2-1 = 1 (1b)
4 = 2^2.  4-1 = 3 (11b)
8 = 2^3.  8-1 = 7 (111b)

以8为例。 1000&amp; 0111 = 0000

因此表达式测试一个数字是不是2的幂。

答案 1 :(得分:14)

那么,第一种情况将检查2 0 == 1.

对于其他情况,num & (num - 1)开始发挥作用:

这就是说如果你拿一个数字,并从一个较低的位掩盖掉,你会得到两个案例中的一个:

  1. 如果数字已经为2的幂,那么少一个将导致只设置了低位的二进制数。使用&将无能为力。

    • 8的示例:0100 & (0100 - 1) - &gt; (0100 & 0011) - &gt; 0000
  2. 如果数字不是2的幂,则少一个不会触及最高位,因此结果至少两个小于num的最大幂。

    • 3的示例:0011 & (0011 - 1) - &gt; (0011 & 0010) - &gt; 0010

    • 13的示例:1101 & (1101 - 1) - &gt; (1101 & 1100) - &gt; 1100

  3. 因此实际表达式会找到所有不是2的幂,包括2 0

答案 2 :(得分:6)

那么,

如果你有X = 1000,那么x-1 = 0111.并且1000&amp;&amp; 0111是0000。

作为2的幂的每个数X具有x-1,其中x位置上的1具有零。按位,0和1总是0。

如果数字x不是2的幂,例如0110. x-1是0101,并且给出0100。

对于0000 - 1111内的所有组合,这导致

   X  X-1 X && X-1  
0000 1111 0000   
0001 0000 0000 
0010 0001 0000
0011 0010 0010
0100 0011 0000
0101 0100 0100
0110 0101 0100
0111 0110 0110
1000 0111 0000
1001 1000 1000
1010 1001 1000
1011 1010 1010
1100 1011 1000
1101 1100 1100
1110 1101 1100
1111 1110 1110

并且无需单独检查1。

答案 3 :(得分:3)

很好地解释here

此外,给定的表达式将0视为2的幂。修复该用法 而是!(x & (x - 1)) && x;

答案 4 :(得分:1)

确定整数是否为2的幂。如果(x & (x-1))为零,则数字为2的幂。

例如,     让x为8(二进制为1000);然后x-1 = 7(0111)。

if    1000
  &   0111
---------------
      0000

C程序演示:

#include <stdio.h>

void main()
{
    int a = 8;
    if ((a&(a-1))==0)
    {
        printf("the bit is power of 2  \n");
    }
    else 
    {
        printf("the bit is not power of 2\n");
    }
}

这会输出the bit is power of 2

#include <stdio.h>

void main()
{
    int a = 7;
    if ((a&(a-1))==0)
    {
        printf("the bit is power of 2  \n");
    }
    else 
    {
        printf("the bit is not power of 2\n");
    }
}

这会输出the bit is not power of 2

答案 5 :(得分:0)

我更喜欢这种依赖于二进制补码的方法:

bool checkPowTwo(int x){
    return (x & -x) == x;
}

答案 6 :(得分:0)

假设n是给定的数字, 如果n是2的幂(n &&!(n&(n-1))将返回1,否则返回0

答案 7 :(得分:-1)

按照C中的程序,将查明数字是2的幂,还能找到2的幂,数字是。

#include<stdio.h>
void main(void)
{
    unsigned int a;
    unsigned int count=0
    unsigned int check=1;
    unsigned int position=0;
    unsigned int temp;
    //get value of a
    for(i=0;i<sizeof(int)*8;i++)//no of bits depend on size of integer on that machine
    {
        temp = a&(check << i);
        if(temp)
        {
            position = i;
            count++;
        }
    }
    if(count == 1)
    {
        printf("%d is 2 to the power of %d",a,position);
    }
    else
    {
        printf("Not a power of 2");
    }
}

还有其他方法可以做到这一点: - 如果数字是2的幂,则只能以二进制格式设置1位

例如8相当于0x1000,从中减去1,我们得到0x0111。

原始编号(0x1000)的结束操作给出0。

如果是这种情况,则该数字是2的幂

    void IsPowerof2(int i)
    {
    if(!((i-1)&1))
    {
    printf("%d" is a power of 2, i);
    }
    }

另一种方式可以是这样的: -

如果我们采用2的幂的补数,

例如8的补码,即0x1000,我们得到0x0111并加1,我们得到

相同的数字,如果是这种情况,则该数字是2的幂

    void IsPowerof2(int i)
    {
    if(((~1+1)&i) == 1)
    {
    printf("%d" is a power of 2,i):
    }
    }