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

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.