Es posible que también desee ver el módulo gmpy. Es una interfaz entre Python y la biblioteca de precisión múltiple de GMP. gmpy proporciona una función invertido que hace exactamente lo que necesita:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Actualizado respuesta
Como señaló @hyh, los gmpy.invert()
devuelve 0 si no existe la inversa. Eso coincide con el comportamiento de la función mpz_invert()
de GMP. gmpy.divm(a, b, m)
proporciona una solución general a a=bx (mod m)
.
>>> gmpy.divm(1, 1234567, 1000000007)
mpz(989145189)
>>> gmpy.divm(1, 0, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 9)
mpz(7)
divm()
devolverá una solución cuando gcd(b,m) == 1
y lanza una excepción cuando no existe el inverso multiplicativo.
Descargo de responsabilidad: Soy el actual mantenedor de la biblioteca gmpy.
actualizada Respuesta 2
gmpy2 ahora plantea adecuadamente una excepción cuando la inversa no existe:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
exponenciación Naive no es una opción debido tiempo (y memoria) límite para cualquier razonablemente grande valor de p como decir 1000000007. – dorserg
exponenciación modular se hace con a lo sumo N * 2 multiplicaciones donde N es el número de bits en el exponente. usando un módulo de 2 ** 63-1, el inverso se puede calcular en el prompt y devuelve un resultado inmediatamente. – phkahler
Guau, increíble. Soy consciente de la exponenciación rápida, simplemente no sabía que la función pow() puede tomar un tercer argumento que lo convierte en exponenciación modular. – dorserg