Skip to main content

How to check if a number is a power of 2


Today I needed a simple algorithm for checking if a number is a power of 2.



The algorithm needs to be:



  1. Simple

  2. Correct for any ulong value.



I came up with this simple algorithm:




private bool IsPowerOfTwo(ulong number)
{
if (number == 0)
return false;

for (ulong power = 1; power > 0; power = power << 1)
{
// this for loop used shifting for powers of 2, meaning
// that the value will become 0 after the last shift
// (from binary 1000...0000 to 0000...0000) then, the for
// loop will break out

if (power == number)
return true;
if (power > number)
return false;
}
return false;
}



But then I thought, how about checking if log 2 x is an exactly round number? But when I checked for 2^63+1, Math.Log returned exactly 63 because of rounding. So I checked if 2 to the power 63 is equal to the original number - and it is, because the calculation is done in double s and not in exact numbers:




private bool IsPowerOfTwo_2(ulong number)
{
double log = Math.Log(number, 2);
double pow = Math.Pow(2, Math.Round(log));
return pow == number;
}



This returned true for the given wrong value: 9223372036854775809 .



Does anyone have any suggestion for a better algorithm?


Source: Tips4allCCNA FINAL EXAM

Comments

  1. There's a simple trick for this problem:

    bool IsPowerOfTwo(ulong x)
    {
    return (x & (x - 1)) == 0;
    }


    Discovery of how and why this works is left as an exercise for the reader, as well as consideration of an obvious edge case.



    Editor's Note

    For completeness, zero is not a power of two. If you want to take into account that edge case, here's how:

    bool IsPowerOfTwo(ulong x)
    {
    return (x != 0) && ((x & (x - 1)) == 0);
    }




    Editor's Note by user JonH

    I figured instead of discovering why this works, why not explain it to those who do not understand.

    First and foremost the bitwise binary & operator from MSDN definition:


    Binary & operators are predefined for the integral types and bool. For
    integral types, & computes the logical bitwise AND of its operands.
    For bool operands, & computes the logical AND of its operands; that
    is, the result is true if and only if both its operands are true.


    Now let's take a look at how this all plays out:

    The function returns boolean (true / false) and accepts one incoming parameter of type unsigned long (x, in this case). Let us for the sake of simplicity assume that someone has passed the value 4 and called the function like so:

    bool b = IsPowerOfTwo(4)

    Now we replace each occurrence of x with 4:

    return (4 != 0) && ((4 & (4-1)) == 0);

    Well we already know that 4 != 0 evals to true, so far so good. But what about:

    ((4 & (4-1)) == 0)

    This translates to this of course:

    ((4 & 3) == 0)

    But what exactly is 4&3

    The binary representation of 4 is 100 and the binary representation of 3 is 011 (remember the & takes the binary representation of these numbers. So we have:

    100=4
    011=3


    Imagine these values being stacked up much like elementary addition. The & operator says that if both values are = 1 then the result is 1, otherwise it is 0. So 1 & 1 = 1, 1 & 0 = 0, 0 & 0 = 0, and 0 & 1 = 0. So we do the math:

    100
    011
    ----
    000


    Cool we are getting somewhere...the end result is simply 0. So we go back and look at what our return statement now translates to:

    return (4 != 0) && ((4 & 3) == 0);

    Which translates now to:

    return true && (0 == 0);

    Which translates to:

    return true && true;

    We all know true && true is simply true, and this shows that for our example, 4 is a power of 2. I hope this helps!

    ReplyDelete
  2. I wrote an article about this recently at http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/. It covers bit counting, how to use logarithms correctly, the classic "x && !(x & (x - 1))" check, and others.

    ReplyDelete
  3. bool IsPowerOfTwo(ulong x)
    {
    return x > 0 && (x & (x - 1)) == 0;
    }

    ReplyDelete
  4. After posting the question I thought of the following solution:

    We need to check if exactly one of the binary digits is one. So we simply shift the number right one digit at a time, and return true if it equals 1. If at any point we come by an odd number ((number & 1) == 1), we know the result is false. This proved (using a benchmark) slightly faster than the original method for (large) true values and much faster for false or small values.

    private static bool IsPowerOfTwo(ulong number)
    {
    while (number != 0)
    {
    if (number == 1)
    return true;

    if ((number & 1) == 1)
    // number is an odd number and not 1 - so it's not a power of two.
    return false;

    number = number >> 1;
    }
    return false;
    }




    Of course, Greg's solution is much better.

    ReplyDelete
  5. bool IsPowerOfTwo( ulong number )
    {
    if( i == 0 ) return false;
    ulong minus1 = i -1;
    return (i|minus1) == (i^minus1);
    }

    ReplyDelete
  6. Here's a simple c++ solution:

    bool IsPowerOfTwo( unsigned int i )
    {
    return std::bitset<32>(i).count() == 1;
    }

    ReplyDelete
  7. bool isPow2 = ((x & ~(x-1))==x)? x : 0;

    ReplyDelete
  8. Find if the given number is a power of 2.

    #include <math.h>

    int main(void)
    {
    int n,logval,powval;
    printf("Enter a number to find whether it is s power of 2\n");
    scanf("%d",&n);
    logval=log(n)/log(2);
    powval=pow(2,logval);

    if(powval==n)
    printf("The number is a power of 2");
    else
    printf("The number is not a power of 2");

    getch();
    return 0;
    }

    ReplyDelete
  9. private static bool IsPowerOfTwo(ulong x)
    {
    var l = Math.Log(x, 2);
    return (l == Math.Floor(l));
    }

    ReplyDelete
  10. bool isPowerOfTwo(int x_)
    {
    register int bitpos, bitpos2;
    asm ("bsrl %1,%0": "+r" (bitpos):"rm" (x_));
    asm ("bsfl %1,%0": "+r" (bitpos2):"rm" (x_));
    return bitpos > 0 && bitpos == bitpos2;
    }

    ReplyDelete
  11. A number is a power of 2 if it contains only 1 set bit. We can use this property and the generic function countSetBits to find if a number is power of 2 or not.

    This is a C++ program:

    int countSetBits(int n)
    {
    int c = 0;
    while(n)
    {
    c += 1;
    n = n & (n-1);
    }
    return c;
    }

    bool isPowerOfTwo(int n)
    {
    return (countSetBits(n)==1);
    }
    int main()
    {
    int i, val[] = {0,1,2,3,4,5,15,16,22,32,38,64,70};
    for(i=0; i<sizeof(val)/sizeof(val[0]); i++)
    printf("Num:%d\tSet Bits:%d\t is power of two: %d\n",val[i], countSetBits(val[i]), isPowerOfTwo(val[i]));
    return 0;
    }


    We dont need to check explicitly for 0 being a Power of 2, as it returns False for 0 as well.

    OUTPUT

    Num:0 Set Bits:0 is power of two: 0
    Num:1 Set Bits:1 is power of two: 1
    Num:2 Set Bits:1 is power of two: 1
    Num:3 Set Bits:2 is power of two: 0
    Num:4 Set Bits:1 is power of two: 1
    Num:5 Set Bits:2 is power of two: 0
    Num:15 Set Bits:4 is power of two: 0
    Num:16 Set Bits:1 is power of two: 1
    Num:22 Set Bits:3 is power of two: 0
    Num:32 Set Bits:1 is power of two: 1
    Num:38 Set Bits:3 is power of two: 0
    Num:64 Set Bits:1 is power of two: 1
    Num:70 Set Bits:3 is power of two: 0

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex