110

I need a function like this:

// return true if 'n' is a power of 2, e.g.
// is_power_of_2(16) => true  
// is_power_of_2(3) => false
bool is_power_of_2(int n);

Can anyone suggest how I could write this?

cigien
  • 57,834
  • 11
  • 73
  • 112
Ant
  • 1,111
  • 3
  • 9
  • 5
  • Possible duplicate of [Find if a number is a power of two without math function or log function](http://stackoverflow.com/questions/19383248/find-if-a-number-is-a-power-of-two-without-math-function-or-log-function) – roottraveller Jan 18 '16 at 03:47
  • @rootTraveller - Probably not a duplicate. C++ and Java are different languages and each offers different facilities. For example, In C/C++ we can now use intrinsics with BMI enabled processors, which issues the machine instruction to do it in once clock. I imagine Java has other things, like maybe something from a Math routine. – jww Sep 20 '16 at 21:52

16 Answers16

235

(n & (n - 1)) == 0 is best. However, note that it will incorrectly return true for n=0, so if that is possible, you will want to check for it explicitly.

http://www.graphics.stanford.edu/~seander/bithacks.html has a large collection of clever bit-twiddling algorithms, including this one.

jbranchaud
  • 5,909
  • 9
  • 45
  • 70
Anonymous
  • 3,388
  • 1
  • 17
  • 4
  • 15
    so basically `(n>0 && ((n & (n-1)) == 0))` – Saurabh Goyal Jul 10 '16 at 08:06
  • 2
    @SaurabhGoyal or `n && !(n & (n - 1))` as the link within the answer states. – Carsten Nov 24 '17 at 10:38
  • Why, oh why, isn't this at the top of the answers? OP please accept. – donturner Mar 06 '18 at 16:06
  • @cassio `!` is a logical operator and hence value of `!(n & (n - 1))` would be a boolean, Are you sure a boolean and a number can be given to a bitwise AND operator? If yes, it looks good. – Saurabh Goyal Jun 19 '19 at 04:03
  • @SaurabhGoyal Yes, I'm sure. A boolean is implicit convertible to an int (`false` is converted to `0`, and `true` to `1`). – Cassio Neri Jun 19 '19 at 18:50
  • 1
    @CassioNeri Your hack doesn't work. For example if n=2, and with `true` converted to 1 you get `10 & 1` which is equal to 0. You have to cast `n` to `bool` as well if you want it to work, ie `bool(n) & !(n & (n - 1))`. – patatahooligan Jan 06 '20 at 14:33
  • By the way, clang does not generate a branch whichever version you use, but gcc does for &&. – patatahooligan Jan 06 '20 at 14:39
  • This would fail for the lower bound of a data type e.g INT_MIN = -2147483648. Instead we should use generic check like ceil(logn) == floor(logn). – WULF Jun 08 '20 at 10:55
89

A power of two will have just one bit set (for unsigned numbers). Something like

bool powerOfTwo = !(x == 0) && !(x & (x - 1));

Will work fine; one less than a power of two is all 1s in the less significant bits, so must AND to 0 bitwise.

As I was assuming unsigned numbers, the == 0 test (that I originally forgot, sorry) is adequate. You may want a > 0 test if you're using signed integers.

Adam Wright
  • 48,938
  • 12
  • 131
  • 152
  • You're missing a '!' or an '==0' –  Sep 20 '08 at 14:43
  • You're also missing a test for negative value of x. – Rob Wells Sep 20 '08 at 14:44
  • Neat, how did you edit it without the 'edited x minutes ago' appearing? –  Sep 20 '08 at 14:45
  • Seriously, how did you just get 120 rep for a demonstrably wrong answer? –  Sep 20 '08 at 14:50
  • @Mike F: Indeed, it does seem people will vote on answers without checking them. Anyone can make a mistake, I guess - if I make any in the future, feel free to edit them out. – Adam Wright Sep 20 '08 at 15:02
  • This is still wrong. Vote my answer up please so I get enough rep to edit it :) – Matt Howells Sep 20 '08 at 15:04
  • @Matt Howells, How is it wrong? @spider57, there is an "odd" feature that if you edit something within X minutes of posting it, it appear in the edit log. It's intended for typos, but has t doesn't he annoying side effect of hiding these changes. – Adam Wright Sep 20 '08 at 15:07
  • *doesn't appear* in the edit log. Sigh. My form today is not good. – Adam Wright Sep 20 '08 at 15:08
  • @Adam cheers. I didn't realise that they had a "typo" filter. @Adam it was wrong for signed ints. But your latest edit fixes that now – Rob Wells Sep 20 '08 at 15:11
52

Powers of two in binary look like this:

1: 0001
2: 0010
4: 0100
8: 1000

Note that there is always exactly 1 bit set. The only exception is with a signed integer. e.g. An 8-bit signed integer with a value of -128 looks like:

10000000

So after checking that the number is greater than zero, we can use a clever little bit hack to test that one and only one bit is set.

bool is_power_of_2(int x) {
    return x > 0 && !(x & (x−1));
}

For more bit twiddling see here.

chappjc
  • 30,359
  • 6
  • 75
  • 132
Matt Howells
  • 40,310
  • 20
  • 83
  • 102
19

In C++20 there is std::has_single_bit which you can use for exactly this purpose if you don't need to implement it yourself:

#include <bit>
static_assert(std::has_single_bit(16));
static_assert(!std::has_single_bit(15));

Note that this requires the argument to be an unsigned integer type.

cigien
  • 57,834
  • 11
  • 73
  • 112
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • 5
    Note that it has been renamed to [`std::has_single_bit`](https://en.cppreference.com/w/cpp/numeric/has_single_bit) and it is defined for unsigned integer types only. For signed integer types you might also want to check whether the value is positive to avoid incorrectly treating minimum signed integer values like INT_MIN as powers of two: `(x > 0) && std::has_single_bit((unsigned)x)`. – Antosha Jan 30 '21 at 23:45
17

Approach #1:

Divide number by 2 reclusively to check it.

Time complexity : O(log2n).

Approach #2:

Bitwise AND the number with its just previous number should be equal to ZERO.

Example: Number = 8 Binary of 8: 1 0 0 0 Binary of 7: 0 1 1 1 and the bitwise AND of both the numbers is 0 0 0 0 = 0.

Time complexity : O(1).

Approach #3:

Bitwise XOR the number with its just previous number should be sum of both numbers.

Example: Number = 8 Binary of 8: 1 0 0 0 Binary of 7: 0 1 1 1 and the bitwise XOR of both the numbers is 1 1 1 1 = 15.

Time complexity : O(1).

http://javaexplorer03.blogspot.in/2016/01/how-to-check-number-is-power-of-two.html

Sam
  • 452
  • 5
  • 15
Raj Dixit
  • 191
  • 1
  • 3
8
bool is_power_of_2(int i) {
    if ( i <= 0 ) {
        return 0;
    }
    return ! (i & (i-1));
}
Rob Wells
  • 36,220
  • 13
  • 81
  • 146
8

for any power of 2, the following also holds.

n&(-n)==n

NOTE: The condition is true for n=0 ,though its not a power of 2.
Reason why this works is:
-n is the 2s complement of n. -n will have every bit to the left of rightmost set bit of n flipped compared to n. For powers of 2 there is only one set bit.

Freeze Francis
  • 517
  • 8
  • 18
6

This is probably the fastest, if using GCC. It only uses a POPCNT cpu instruction and one comparison. Binary representation of any power of 2 number, has always only one bit set, other bits are always zero. So we count the number of set bits with POPCNT, and if it's equal to 1, the number is power of 2. I don't think there is any possible faster methods. And it's very simple, if you understood it once:

if(1==__builtin_popcount(n))
F10PPY
  • 99
  • 1
  • 3
  • Nope. I just tested this. I love popcount but for the power-of-2 test, the test `i && !(i & (i - 1)))` is about 10% faster on my machine, even when I was sure to enable the native assembly POPCNT instruction in gcc. – eraoul Feb 22 '20 at 20:35
  • Oops I take it back. My test program was running in a loop and branch prediction was "cheating". You're right, if you have the POPCNT instruction on your CPU it's faster. – eraoul Feb 23 '20 at 00:10
  • 1
    Note that for non-x86 architectures calculating the population count may be slower than the traditional check. For instance, on AArch64 it usually takes 4 instructions: `fmov`, `cnt`, `addv`, `fmov`, where the first `fmov` instruction copies the value from a general-purpose register to a SIMD register and the last `fmov` instruction copies the calculated population count back to a general-purpose register. – Antosha Jan 31 '21 at 00:26
3
return n > 0 && 0 == (1 << 30) % n;
2

Following would be faster then most up-voted answer due to boolean short-circuiting and fact that comparison is slow.

int isPowerOfTwo(unsigned int x)
{
  return x && !(x & (x – 1));
}

If you know that x can not be 0 then

int isPowerOfTwo(unsigned int x)
{
  return !(x & (x – 1));
}
Margus
  • 19,694
  • 14
  • 55
  • 103
1

This isn't the fastest or shortest way, but I think it is very readable. So I would do something like this:

bool is_power_of_2(int n)
  int bitCounter=0;
  while(n) {
    if ((n & 1) == 1) {
      ++bitCounter;
    }
    n >>= 1;
  }
  return (bitCounter == 1);
}

This works since binary is based on powers of two. Any number with only one bit set must be a power of two.

Jere.Jones
  • 9,915
  • 5
  • 35
  • 38
  • It may not be fast or short, but it's correct unlike the top answers. –  Sep 20 '08 at 15:00
  • 2
    At time of commenting they were all bugged. They have since been edited into an acceptable state. –  Sep 25 '08 at 04:33
1

What's the simplest way to test whether a number is a power of 2 in C++?

If you have a modern Intel processor with the Bit Manipulation Instructions, then you can perform the following. It omits the straight C/C++ code because others have already answered it, but you need it if BMI is not available or enabled.

bool IsPowerOf2_32(uint32_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
    return !!((x > 0) && _blsr_u32(x));
#endif
    // Fallback to C/C++ code
}

bool IsPowerOf2_64(uint64_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
    return !!((x > 0) && _blsr_u64(x));
#endif
    // Fallback to C/C++ code
}

GCC, ICC, and Clang signal BMI support with __BMI__. It's available in Microsoft compilers in Visual Studio 2015 and above when AVX2 is available and enabled. For the headers you need, see Header files for SIMD intrinsics.

I usually guard the _blsr_u64 with an _LP64_ in case compiling on i686. Clang needs a little workaround because it uses a slightly different intrinsic symbol nam:

#if defined(__GNUC__) && defined(__BMI__)
# if defined(__clang__)
#  ifndef _tzcnt_u32
#   define _tzcnt_u32(x) __tzcnt_u32(x)
#  endif
#  ifndef _blsr_u32
#    define  _blsr_u32(x)  __blsr_u32(x)
#  endif
#  ifdef __x86_64__
#   ifndef _tzcnt_u64
#    define _tzcnt_u64(x) __tzcnt_u64(x)
#   endif
#   ifndef _blsr_u64
#     define  _blsr_u64(x)  __blsr_u64(x)
#   endif
#  endif  // x86_64
# endif  // Clang
#endif  // GNUC and BMI

Can you tell me a good web site where this sort of algorithm can be found?

This website is often cited: Bit Twiddling Hacks.

OmG
  • 18,337
  • 10
  • 57
  • 90
jww
  • 97,681
  • 90
  • 411
  • 885
  • This is certainly not the "simplest way" as requested in the OP, but arguably the fastest for specific environments. Showing how to conditionalize for different architectures is tremendously useful. – fearless_fool Oct 11 '19 at 17:10
  • The `!!((x > 0) && _blsr_u32(x))` condition is not correct, it should read `(x > 0) && (_blsr_u32(x) == 0)`. – Antosha Jan 31 '21 at 02:41
0

Here is another method, in this case using | instead of & :

bool is_power_of_2(int x) {
    return x > 0 && (x<<1 == (x|(x-1)) +1));
}
Chethan
  • 905
  • 1
  • 10
  • 18
-1

It is possible through c++

int IsPowOf2(int z) {
double x=log2(z);
int y=x;
if (x==(double)y)
return 1;
else
return 0;
}
Jay Ponkia
  • 900
  • 1
  • 8
  • 15
  • 3
    That's neither simple, nor fast, to me. – luk32 Sep 14 '15 at 12:55
  • 4
    I.e. it's certainly not fast due to `log2`, and proof that it works is not so easy to explain (precisely, can you get caught by rounding errors?). It's also needlessly convoluted with `if..return..else..return`. What's wrong with collapsing it to `return x==(double)y;` ? It should return `bool` anyayws. IMO even ternary operator would be clearer if one really wants to stick to `int`. – luk32 Sep 14 '15 at 13:01
-2

Another way to go (maybe not fastest) is to determine if ln(x) / ln(2) is a whole number.

MikeJ
  • 14,430
  • 21
  • 71
  • 87
-5

This is the bit-shift method in T-SQL (SQL Server):

SELECT CASE WHEN @X>0 AND (@X) & (@X-1)=0 THEN 1 ELSE 0 END AS IsPowerOfTwo

It is a lot faster than doing a logarithm four times (first set to get decimal result, 2nd set to get integer set & compare)

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 6
    It is good to see how the top answer to this question can also be implemented in T-SQL, but that isn't really relevant to the question asked here. An alternative (if you were looking for a solution in T-SQL, found this answered question , implemented it in T-SQL and thought it interesting enough to post this answer) would be to post the question with reference to T-SQL, then answer it yourself, with reference to this answered question. Hope this suggestion is helpful. – Simon Feb 02 '13 at 02:03
  • this doesn't really answer this question – phuclv Mar 11 '15 at 05:46