1 """
2 如果一个数恰好等于它的因子之和,则称该数为“完全数” 。各个小于它的约数(真约数,列出某数的约数,去掉该数本身,剩下的就是它的真约数)的和等于它本身的自然数叫做完全数(Perfect number),又称完美数或完备数。
3 例如:
4 第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。
5 第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
6 第三个完全数是496,有约数1、2、4、8、16、31、62、124、248、496,除去其本身496外,其余9个数相加,1+2+4+8+16+31+62+124+248=496。后面的完全数还有8128、33550336等等。
7 特有性质
8 (1)所有的完全数都是三角形数。
9 (2)所有的完全数的倒数都是调和数。
10 (3)可以表示成连续奇立方数之和。
11 (4)都可以表达为2的一些连续正整数次幂之和。
12 (5)完全数都是以6或8结尾。
13 (6)各位数字辗转式相加个位数是1。
14 (7)它们被3除余1、被9除余1、1/2被27除余1。
15 计算方法
16 推导公式:
17 大数学家欧拉曾推算出完全数的获得公式:如果p是质数,且2^p-1也是质数,那么(2^p-1)X2^(p-1)便是一个完全数。
18 例如p=2,是一个质数,2^p-1=3也是质数,(2^p-1)X2^(p-1)=3X2=6,是完全数。
19 但是2^p-1什么条件下才是质数呢?事实上,当2^p-1是质数的时候,称其为梅森素数。
20 """
21 perfectnumber = 1 #完全数的开始值
22 while True:
23 #判断是否是完全数,如果是则打印
24 List = [] # 每次循环开始都创建一个新列表,用来存因数
25 for ax in range(1,perfectnumber):
26 if perfectnumber % ax ==0: #如果 ax 是 perfectunmber的因数
27 List.append(ax) # 放在列表中,此时List列表中perfectnumber所有的因数
28 if sum(List) == perfectnumber:
29 print(perfectnumber,'是完全数')
30 perfectnumber += 1
31
32 #c/c++嵌套的python,即cython
33 import datetime
34 def isPrime(N):
35 if N < 4: return N > 1
36 if ((N & 1) == 0): return False
37 i = 3
38 while i * i <= N :
39 if (N % i) == 0 : return False
40 i += 2
41 return True
42 def primality(N, M):
43 if N == 2 : return True
44 s = 4
45 for i in range(0, N - 2) :
46 s = (s * s - 2) % M
47 return s == 0
48 def findPerfectNumber() :
49 count = 0
50 begin = datetime.datetime.now()
51 strContent = ""
52 for i in range(2, 5000):
53 M = (1 << i) - 1
54 t = M << (i-1)
55 # 当p为素数且梅森数2^p-1为素数时2^(p-1)*(2^p-1)为完全数
56 if isPrime(i) and primality(i,M) :
57 count += 1
58 numLen = len(str(t))
59 strContent = strContent + "第" + str(count) + "个" + str(numLen) + "位数:" + str(t) + "\r\n"
60 end = datetime.datetime.now()
61 print(strContent)
62 print("FindPerfectNumber运行花费时间为:", (end - begin).total_seconds(), "s")
63 findPerfectNumber()