I want to check if a number x is an exponential power of another number, y. I understand mathematics: use logarithms.
However, when I did this approach in Python3, using log() function, I got weird results. I wanted to test whether 243 is a power of 3, which it is, my code returned False. My code is as follows:
power = log(n, 3)
if (int(power)) == power:
return True
I get 4.999999999999999 as the result in power
. I read about the precision and other tactical details pertaining to floating points and logarithms in Python3 and I tried those solutions but none of them gave me the answer that I know is correct as far as basic maths is concerned.
I tried this:
from math import log
from decimal import Decimal, Context
class Power:
def power_func(self, n: int) -> bool:
if n == 0:
return False
ctx = Context(prec=20)
power = log(n, Decimal(3))
if (int(power)) == power:
return True
return False
I think I am missing some basics of Python here but not sure how to proceed further. I know other solutions to do the task but I wanted to achieve this using logarithms in Python3.
Don't use logarithms; they rely on real arithmetic to work correctly, which Python cannot do.
Instead, use repeated squaring to approach n
from the base.
def is_power_of(n, b):
y = b
# Compute y = b**2, b**4, ..., b**2**i until y reaches or exceeds n
# i = 1
while y < n:
y = y * y
# i *= 2
# If we overshoot, divide by b until we either
# reach n or get a non-zero remainder
while y > n:
y, r = divmod(y, b)
# i -= 1
if r:
return False
else:
return y == n
Note that if the function returns true, i
will be the value such that b**i == n
.