Четыре подхода: одностадийный, итеративный, другой итеративный, позволяющий избежать чрезмерного умножения, бинарный поиск для работы с очень большими пределами
import math
def maxpow(n, limit):
return n**math.floor(math.log(limit) / math.log(n))
def maxpowit(n, limit):
x = 1
while (x * n < limit):
x *= n
return x
def maxpowit2(n, limit):
x, y = 1, n
while (y < limit):
x, y = y, y * n
return x
def maxpowbs(n, limit):
stack = []
x, y = 1, n
while (y < limit):
stack.append(y)
x, y = y, y * y
#here stack holds values n^(2^i)
#like [2, 4, 16, 256, 65536, 4294967296]
for i in reversed(range(len(stack)-1)):
y = stack[i]
if (x * y < limit):
x *= y
return x
print(maxpow(2, 500), maxpowit(2, 500))
>>> 256 256
print(maxpowbs(2, 1152921504606846997))#2^60 + xxx
>>>1152921504606846976 #2^60 exactly