Precisión de troncos en python

A continuación se muestra un código fuente que verifica si un número puede expressse en potencia, pero ¿por qué falla el código para n = 76 ** 89 - 1 y n = 76 ** 89 ? ¿Cómo puedo solucionar este error? Para ambos n da x=log(n,2)/log(i,2)=89.0

 from math import log,sqrt,floor import sys n= 76 ** 89 - 1 t=floor(sqrt(n))+1 flag=False for i in range(2,t): x=log(n,2)/log(i,2) print(x) if x-int(x)<sys.float_info.epsilon: print("YESSSSSSSSSSSSS!") flag=True break if not flag: print("Nooooooooooooooooooo!") 

Su código solo encuentra candidatos pero no comprueba si realmente coinciden. La inexactitud del punto flotante hace que no pueda marcar la diferencia entre un valor muy grande como este y este mismo valor menos uno.

Pero como Python tiene un número ilimitado de artímeticos enteros de rango, puede comprobar que lo que encontró es realmente una coincidencia.

Mi idea: una vez que encuentre la potencia, calcule el número teórico de potencia (redondeando), luego calcule la potencia en números enteros y compare los enteros.

 from math import log,sqrt,floor import sys n = 76 ** 89 t=floor(sqrt(n))+1 flag=False for i in range(2,t): x=log(n,i) # faster than x=log(n,2)/log(i,2) if x-int(x) 

con el valor 76 ** 89 - 1 , se obtiene "pero no es exacto" porque la potencia calculada no coincide con el valor n .

Aparte: es más rápido usar x=log(n,i) lugar de x=log(n,2)/log(i,2) y probablemente sea más preciso también, ya que están implicadas menos operaciones de flotación.