π‘ Problem Formulation: We often encounter situations in coding where we need to determine if a given integer is a power of two. This check can be useful in various contexts, such as bit manipulation, optimization problems, or while working with binary trees. To illustrate, if an input is 8, the desired output would be True as 8 is 2 to the power of 3. Conversely, if the input is 7, the output should be False.
Method 1: Iterative Division
This method involves continuously dividing the number by two, checking if it’s divisible without a remainder. If we eventually reach 1, the original number is a power of two. The function stops early if a division has a remainder, returning False.
Here’s an example:
def is_power_of_two(n):
if n <= 0:
return False
while n % 2 == 0:
n //= 2
return n == 1
print(is_power_of_two(32))
print(is_power_of_two(7))The output will be:
True False
This method effectively reduces the number until it can be determined whether it is a power of two. It is straightforward but can be slower for large numbers since it performs multiple division operations.
Method 2: Bitwise AND with the Preceding Number
Using bitwise operations, we can determine if a number is a power of two by checking if it has exactly one bit set to 1 (since powers of two are represented as such in binary). Thus, we perform an AND operation between the number and its predecessor; if the result is 0, the number is a power of two.
Here’s an example:
def is_power_of_two(n):
return n > 0 and (n & (n - 1)) == 0
print(is_power_of_two(8))
print(is_power_of_two(14))The output will be:
True False
This method is very efficient since it completes in constant time regardless of the size of the number, making it suitable for large integers.
Method 3: Logarithmic Check
A mathematical approach involves using logarithms. We use the base-2 logarithm of the number and check if the result is an integer. If it is, the number is a power of two. This method relies on the property that logarithms can revert exponentiation.
Here’s an example:
import math
def is_power_of_two(n):
if n <= 0:
return False
log_result = math.log(n, 2)
return log_result.is_integer()
print(is_power_of_two(256))
print(is_power_of_two(245))The output will be:
True False
This method is precise and works well, but may suffer from floating-point representation errors for very large numbers and might not be as fast as bitwise operations.
Method 4: Power of Two Set
Another way to check if a number is a power of two is to precalculate a set of powers of two within a range and simply check the membership of the given number in that set. It’s very quick for numbers within the precalculated range.
Here’s an example:
powers_of_two = {1 << exp for exp in range(0, 31)} # Assuming 32-bit integer
def is_power_of_two(n):
return n in powers_of_two
print(is_power_of_two(1024))
print(is_power_of_two(1023))The output will be:
True False
While this is a fast method for a fixed range of numbers, it is not practical for very large numbers beyond the precalculated range and consumes memory for the set.
Bonus One-Liner Method 5: Using Bit Counting
A fast and clever one-liner uses the built-in Python function bin() to check if the binary representation of the number contains only one ‘1’. It’s a concise version of the bitwise AND method.
Here’s an example:
is_power_of_two = lambda n: n > 0 and bin(n).count('1') == 1
print(is_power_of_two(64))
print(is_power_of_two(65))The output will be:
True False
This one-liner is readable and efficient for small to moderately large numbers, leveraging Python’s built-in capabilities.
Summary/Discussion
- Method 1: Iterative Division. Easy to understand. Slower for large numbers due to multiple divisions.
- Method 2: Bitwise AND. Extremely fast and efficient. Operates in constant time, best for performance-critical applications.
- Method 3: Logarithmic Check. Mathematically elegant. Can suffer from floating-point errors with very large numbers and is not as fast as bitwise methods.
- Method 4: Power of Two Set. Quick for numbers in the precalculated range. Consumes memory for the set and not suitable for numbers beyond this range.
- Bonus Method 5: One-liner Using Bit Counting. Compact and Pythonic, leveraging built-in functions. Efficiency may decrease with very large numbers.
