使用Lucas-Lehmer primality test来检查什么素数产生梅森素数(Mp),这样就避免了检查梅森数本身的素性,因为它们非常大,而且只有素数指数产生Mp,通过这个测试,你只需要p是素数并通过这个测试,那么你就可以把你的完美数构建成((2^p)-1)(2^(p-1))。在
通过这个测试,我可以在我的机器上找到前16个p[2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203],它们在我的机器上产生了一个MPEN12SEG,有点老旧,是奔腾的3GHz双核
下面是代码(在python3.3中),您还可以使用更强大的素性测试,如Miller-Rabin test或Baillie PSW,这些不同于trial division的代码不会花太长时间来检查大量的数字。在def primality_Test_Trial_Division(n:int) -> bool:
if n >= 0 :
if n<2:
return False
elif n<4:
return True
elif not n&1 or n%3==0:
return False
else:
mid = 1 + int( n**0.5 )
i = 5
while i
i += 2
return i>=mid
else:
raise ValueError
isPrime = primality_Test_Trial_Division
def primality_Test_LL(p:int) -> bool:
"""Lucas–Lehmer primality test. Check if Mp = 2^p − 1 is prime.
en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test"""
if isPrime(p):
if p==2:
return True
mersenne = (2**p)-1 #Mp
s = 4
for x in range( p-2 ):
s = pow(s,2,mersenne)-2
#Performing the mod Mp at each iteration ensures
#that all intermediate results are at most p bits
#(otherwise the number of bits would double each iteration).
#The same strategy is used in modular exponentiation.
return s==0
else:
return False
import itertools
def perfect_numbers(n:int):
"""print the first n perfect numbers"""
perfect = 0
for p in itertools.count(2):
if primality_Test_LL(p):
print(p,"is the Mersenne Prime for the perfect number:",(2**(p-1))*((2**p)-1))
perfect += 1
if perfect >= n:
break