Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to check if a number is a power of base b?

In python, how can you check if a number n is an exact power of base b?

Note: it needs to be generalized to any base which is given as a parameter.

Here is what I got:

Assume n and base are integers > 0.

import math
def is_power(n,base):
    return math.log(n,base) == base**n
like image 848
omega Avatar asked Mar 12 '13 03:03

omega


People also ask

How do you check if a is a power of B?

A number, a, is a power of b if it is divisible by b and a/b is a power of b.

How do you check if a number is a power of something?

A simple solution is to repeatedly compute powers of x. If a power becomes equal to y, then y is a power, else not.

How do you check if a number is a perfect power?

An integer n > 1 is a perfect power if there are integers x and k > 1 with n = xk. Note that k ≤ log2 n; also, the minimal k is prime. A perfect-power detection algorithm is an algorithm that, given an integer n > 1, figures out whether n is a perfect power.


1 Answers

First, assuming you have a specific logarithm operator (many languages provide logarithms to base 10 or base e only), logab can be calculated as logxb / logxa (where x is obviously a base that your language provides).

Python goes one better since it can work out the logarithm for an arbitrary base without that tricky equality above.

So one way or another, you have a way to get logarithm to a specific base. From there, if the log of b in base a is an integer(note 1), then b is a power of a.

So I'd start with the following code, now with added edge-case detection:

# Don't even think about using this for negative powers :-)

def isPower (num, base):
    if base in {0, 1}:
        return num == base
    power = int (math.log (num, base) + 0.5)
    return base ** power == num

See for example the following complete program which shows this in action:

import math

def isPower (num, base):
    if base in {0, 1}:
        return num == base
    power = int (math.log (num, base) + 0.5)
    return base ** power == num

print isPower (127,2)       # false
print isPower (128,2)       # true
print isPower (129,2)       # false
print

print isPower (26,3)        # false
print isPower (27,3)        # true
print isPower (28,3)        # false
print isPower (3**10,3)     # true
print isPower (3**129,3)    # true
print

print isPower (5,5)         # true
print isPower (1,1)         # true
print isPower (10,1)        # false

If you're the sort that's worried about floating point operations, you can do it with repeated multiplications but you should test the performance of such a solution since it's likely to be substantially slower in software than it is in hardware. That won't matter greatly for things like isPower(128,2) but it may become a concern for isPower(verybignum,2).

For a non-floating point variant of the above code:

def isPower (num, base):
    if base in {0, 1}:
        return num == base
    testnum = base
    while testnum < num:
        testnum = testnum * base
    return testnum == num

But make sure it's tested against your largest number and smallest base to ensure you don't get any performance shocks.


(Note 1) Keep in mind here the possibility that floating point imprecision may mean it's not exactly an integer. You may well have to use a "close enough" comparison.

like image 143
paxdiablo Avatar answered Oct 24 '22 13:10

paxdiablo