Это реализация Миллера-Рабина, которую я написал некоторое время назад.Это никогда не давало мне неожиданного результата - хотя это не значит, что не будет!Он практически идентичен тому, который вы вставили, и объявляет 99999999999999997 простым.Ваш сделал то же самое, когда я проверял это - так что это секунда к мнению Миколы . Но посмотрите ниже на одну возможную проблему, которую я не могу легко проверить ... поцарапайте ее, я проверил ее, и это была проблема .
Когда дело доходит до тестирования простоты, яЯ не эксперт, но я потратил много времени на размышления и понимание Миллера-Рабина, и я уверен, что ваша реализация точная.
def is_prime_candidate(self, p, iterations=7):
if p == 1 or p % 2 == 0: return False
elif p < 1: raise ValueError("is_prime_candidate: n must be a positive integer")
elif p < self.maxsmallprime: return p in self.smallprimes
odd = p - 1
count = 0
while odd % 2 == 0:
odd //= 2
count += 1
for i in range(iterations):
r = random.randrange(2, p - 2)
test = pow(r, odd, p)
if test == 1 or test == p - 1: continue
for j in range(count - 1):
test = pow(test, 2, p)
if test == 1: return False
if test == p - 1: break
else: return False
print i
return True
Единственное, что я заметил в вашем коде, который показался мне необычным, это:
d = int(nn / (2 ** s))
Почему int
, подумал я про себя.Тогда я понял, что вы должны использовать Python 3. Это означает, что вы выполняете арифметику с плавающей запятой и затем конвертируете в int.Это казалось сомнительным.Поэтому я проверил его на ideone. И вот! результат был False
.Поэтому я изменил код, чтобы использовать явное разделение по полу (d = nn // (2 ** s)
). И вот! это было True
.