Możesz również spojrzeć na moduł gmpy . Jest to interfejs między Pythonem a biblioteką o wielu precyzjach GMP. gmpy zapewnia funkcję odwracania, która robi dokładnie to, czego potrzebujesz:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Zaktualizowana odpowiedź
Jak zauważono w @hyh, gmpy.invert()
zwraca 0, jeśli odwrotność nie istnieje. To pasuje do zachowania funkcji GMP mpz_invert()
. gmpy.divm(a, b, m)
zapewnia ogólne rozwiązanie 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()
zwróci rozwiązanie, gdy gcd(b,m) == 1
i zgłosi wyjątek, gdy funkcja multiplikatywna odwrotna nie istnieje.
Zastrzeżenie: jestem obecnym opiekunem biblioteki gmpy.
Zaktualizowana odpowiedź 2
gmpy2 teraz poprawnie zgłasza wyjątek, gdy odwrotność nie istnieje:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
pow
funkcji dla tego:y = pow(x, -1, p)
. Zobacz bugs.python.org/issue36027 . Od zadania pytania do rozwiązania pojawiającego się w bibliotece standardowej minęło zaledwie 8,5 roku!