The problem requires you to write a function isPowerOf4 to check whether a given positive integer is a power of 4. Ideally your implementation should not contain a loop. This is a natural extension to the classical bit operations problem which asks you to write a function isPowerOf2 that checks if a positive integer is a power of 2.

Notice that a positive integer x is a power of 2 if and only if exactly one bit (except for the leading bit) is set (equals 1) in its binary representation. What happens if we do x & (x-1)?

When x = 0b111, x & (x-1) = 111 & 110 = 110.

When x = 0b101, x & (x-1) = 101 & 100 = 100.

When x = 0b100, x & (x-1) = 100 & 011 = 0.

It's not hard to see that x & (x-1) effectively turns one set bit of x to 0. So to check if positive integer x is a power of 2, we can simply compare x & (x-1) with 0:

def isPowerOf2(x):
    return not x & (x-1)

Since each iteration of x & (x-1) turns off one set bit of x, a simple while loop can count the number of sets bits of a given integer in time O(k) instead of O(sizeof(int)) where k is the number of set bits of the given integer.

def numOfSetBits(x):
    count = 0
    while x:
        x &= x - 1
        count += 1
    return count

Of course, isPowerOf2 can be implemented to check if the result of numOfSetBits equals 1. But this way x & (x-1) will be iterated k times instead of 1.

For a positive integer x to be a power of 4, it's necessary that x be a power of 2. What are some other requirements? Let's write down some positive integers in their binary forms:

2: 10
4: 100
8: 1000
16: 10000

Notice that in order for x to be a power of 4, its only set bit should be at the third, fifth or seventh, etc bit counting from the right. How do we check that? By creating a mask 0b01010101010101010101010101010101 which is 0x55555555 in hex.

The following snippet completes the task:

def isPowerOf4(x):
    mask = 0x55555555
    return isPowerOf2(x) and bool(x & mask)

isPowerOf2(x) checks that x contains exactly one set bit and bool(x & mask) checks that the correct bit is set.

results matching ""

    No results matching ""