Since I already have an accepted answer here, I'll use this one to explain a bit why your approach is bad:
It uses recursion in python. Python needs to open up a stack frame for every call, so for very large numbers, this will be a bad way of solving this. It will even fail for very large integers.
I don't even think recursion in a non-purely-functional language like python is the intuitive thing to do here. There's a million easier ways to do this; for example, a while
loop:
n = int(n)
while n>1:
if n/2 != n/2.0: #compare integer division to float division
return False
n = n/2
return True
Checking against power of two can be done in clever ways by realizing what the storage structure for integers on computers is: it's binary. So you could just count the binary 1
s in your int
's binary representation:
return bin(n).count('1') == 1
would also work. Of course, that would mean that python internally converts the integer to a string, which wastes memory on large numbers. So you might as well
power_of_2 = 1
while power_of_2 <= n:
if power_of_2 == n:
return True
power_of_2 *= 2
return False
simply compares your number to all smaller-or-equal powers of two. (which of course would probably take longer and use more memory, since your python interpreter will have to interpret python instead of just converting your integer to a string in C, but this is about algorithmic principles, right?) That way, you don't need to reserve memory just to count occurencies of 1 in your binary representation.
Of course, there's a one-liner that solves your issues, and I take it from the things I've learned writing in C/C++:
bool(n and not (n&(n-1)))
To explain n and not (n&(n-1))
: n
is True iff n != 0
, which is would otherwise falsely qualify as power of 2.
For not (n&(n-1))
: n&(n-1)
checks whether something is not a power of 2, so we have to invert that. &
is the bitwise "and" operator. To understand n & (n-1)
, imagine n
is a power of 2, let's say 8
. So n-1 == 7
, and thus
8|0b1000
7|0b0111
--------
&|0b0000
as you can see, for all powers of two, n&(n-1)
is 0
, which evaluates to False
. For all non-powers of two, you'll don't invert all the bits when subtracting 1
, so n&(n-1) != 0
, which evaluates to True
.