For example, 243 is a perfect power of 3 because 243=3^5.
I've previously been using (math.log(a) / math.log(b)).is_integer()
, which I thought worked fine, but then I tried it with the example above and it actually returns 4.999999999999999 due to floating point arithmetic. So it's only reliable for very small numbers, less than around 100 I've found.
I suppose I could use a loop to do repeated multiplication... i.e. set i to 3, then 9, then 27, then 81, then 243, which equals the target, so we know it's a perfect power. If it reaches a point where it's bigger than 243 then we know it's not a perfect power. But I'm running this check within a loop as it is, so this seems like it'd be very inefficient.
So is there any other way of reliably checking if a number is a perfect power of another?
Try:
b ** int(round(math.log(a, b))) == a
That is, only use log()
(note there is a 2-argument form!) to get a guess at an integer power, then verify whether "that works".
Note that math.log()
returns a sensible result even for integer arguments much too large to represent as a float. Also note that integer **
in Python is exact, and uses an efficient algorithm internally (doing a number of multiplications proportional to the number of bits in the exponent).
This is straightforward and much more efficient (in general) than, say, repeated division.
But then I'm answering the question you asked ;-) If you had some other question in mind, some of the other answers may be more appropriate.
maybe something like:
def is_perfect_power(a, b):
while a % b == 0:
a = a / b
if a == 1:
return True
return False
print is_perfect_power(8,2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With