Если вы замените
odd_num = (number - 1) / (2 ** power_of_two)
от
odd_num = (number - 1) // (2 ** power_of_two)
ваш код будет работать - но довольно медленно для больших чисел. Чтобы улучшить код:
- Используйте более простой метод вычисления
odd_num
и power_of_two
- Используйте
pow()
для модульного возведения в степень.
Что-то вроде:
from random import randint
def miller_rabin_is_prime(number, k=10):
if number < 2:
return False
elif number <= 3:
return True
else:
odd_num = number - 1
power_of_two = 0
while odd_num % 2 == 0:
power_of_two += 1
odd_num //= 2
for _ in range(k):
random = randint(2, number - 2)
checker = pow(random,odd_num, number)
if (checker == 1) or (checker == number - 1):
continue
try:
for loop in range(power_of_two - 1):
checker = pow(checker,2,number)
if checker == number - 1:
raise TypeError
except TypeError:
continue
return False
return True
Тогда, например, miller_rabin_is_prime(1000003)
будет оцениваться до True
почти мгновенно, тогда как ваш исходный код (даже после замены /
на //
) займет около 15 секунд из-за немодулярного возведения в степень.
В качестве последнего замечания вы используете обработку ошибок для условий, не связанных с ошибками (ясно, что при checker == number - 1
ошибка типа отсутствует). Было бы намного чище реорганизовать ваш основной цикл, чтобы он не использовал try--except
. Обработка ошибок не предназначена для обычного потока управления.