Você também pode querer dar uma olhada no módulo gmpy . É uma interface entre o Python e a biblioteca de precisão múltipla GMP. gmpy fornece uma função invert que faz exatamente o que você precisa:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Resposta atualizada
Conforme observado por @hyh, o gmpy.invert()
retorna 0 se o inverso não existe. Isso corresponde ao comportamento da mpz_invert()
função GMP . gmpy.divm(a, b, m)
fornece uma solução geral para 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()
retornará uma solução quando gcd(b,m) == 1
e levanta uma exceção quando o inverso multiplicativo não existe.
Aviso: Sou o mantenedor atual da biblioteca gmpy.
Resposta atualizada 2
O gmpy2 agora gera uma exceção corretamente quando o inverso não existe:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
pow
função para isso:y = pow(x, -1, p)
. Consulte bugs.python.org/issue36027 . Demorou apenas 8,5 anos desde a pergunta feita até que uma solução aparecesse na biblioteca padrão!