费马小定理:
如果 n 是一个素数,a 是小于 n 的任意正整数,那么 a 的 n 次方与 a 模 n 同余。(两个数称为是模 n 的同余,如果它们除以 n 的余数相同。数 a 除以 n 的余数称为 a 取模 n 的余数,或简称为 a 取模 n)。
如果 n 不是素数,那么,一般而言,大部分的 a < n 都将满足上面的关系。这就引出了下面这个检查素数的算法:
对于给定的整数 n,随机任取一个 a < n 并计算出 an 取模 n 的余数。如果得到的结果不等于 a,那么 n 就肯定不是素数。如果它就是 a,那么 n 是素数的机会就很大。现在再另取一个随机的 a 并采用同样的方式检查。如果它满足上述等式,那么我们就能对 n 是素数有更大的信心了。通过检查越来越多的 a 值,我们就可以不断增加对有关结果的信心。这一算法称为费马检查。
读起来理解不直观?那么我这么总结下吧。
假如a是一个整数,p是一个素数,那么 ap = a (mod p)
如果a不是p的倍数,这个定理也可以写成 ap-1 = 1 (mod p)
举个例子,67是一个素数,则266 mod 67 = 1。
import random def expmod(base,exp,m): if exp==0: return 1 elif exp%2==0: return expmod(base,exp/2,m)**2 % m else: return expmod(base,exp-1,m)*base % m def fermat_test(n): a=random.randint(1,n-1) if a==expmod(a,n,n): return 1 else: return 0 def fermat_prime(n,time): if time==0: return 1 elif fermat_test(n)==1: return fermat_prime(n,time-1) else: return 0 #print fermat_test(11) print fermat_prime(99,100)
对于为啥不直接用 a^exp 来求幂值 解释如下:
【转】http://www.blogjava.net/killme2008/archive/2007/05/11/116813.html
直接定义(expmod base exp m)为base^exp基于m的模(modulo)
(define (expmod base exp m)
(remainder (fast-expt base exp) m))
在理想情况下是正确的,在语义上与原定义是等价的,甚至递归层数
都是一样的,而且更加直观。
但在实践中,这样的定义是不可行的,这也是为什么我们要采用原文中的定义
的原因:因为base^exp很可能是一个非常大的数。比如,当我们取第二个
测试例子中的n=1000000时,base是[1,999999]区间中的任意
随机数,它的平均取值为50000,而exp=1000000。50000^1000000是一个大得
惊人的数,无论是fast-expt的层层函数调用计算,还是用remainder对其取模,
计算量都是很大的。
而相反,原始的expmod函数
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
通过分解(a*b mod n) 为 ((a mod n) * (b mod n) mod n),使得每层递归
调用的计算参数和返回值总是小于n (x mod n < n),即便是计算过程中出现
的最大数(a mod n) * (b mod n) 也依然是要小于n^2, 相对于前者n^n的数
量级,实在是小得多,这样就避免了大数的计算问题。
比如经测试,在使用新的expmod的情况下,1009的验证需要1.2ms的时间,
1000003的验证需要 93680ms,远高于原来的expmod函数。
这也同时印证了我们在1.24题中的分析,同样的操作在不同字长的数字上的
代价是不同的。1000000的验证时间现在是1000的8000多倍,远不再是2倍左右
的关系。在1.24中的,因为expmod算法的控制,操作数最多是n^2级的,字长
所引起的差距并不明显,只在10^6-10^12间产生了一点点阶跃;而这里的算法
中, 操作数可以达到n^n级,当n=1000时,1000^1000的字长大约在10000位(二
进制数)左右,而n=1000000时1000000^1000000的字长则达到在20000000位(二
进制数)左右,这字长的巨大差距导致了我们在1.24中已经发现的问题更加明显。
相关推荐
本文实例讲述了Python素数检测的方法。分享给大家供大家参考。具体如下: 因子检测: 检测因子,时间复杂度O(n^(1/2)) def is_prime(n): if n < 2: return False for i in xrange(2, int(n**0.5+1)): if n%i...
费马素性检验是一种随机化算法,判断一个数是合数还是可能是素数。 根据费马小定理:如果p是素数,<math>1 \le a \le p,那么 <math>a^ \equiv 1 \pmod。 如果我们想知道n是否是素数,我们在中间选取a,看看上面...
本代码采用C语言,基于vc6.0+miracl5.5.4。运用费马小定理和概率性算法对大整数的素性检测(大整数从txt文档读入)
费马大定理.pdf
利用vb程序来画费马线。方便快捷地进行图像的识别。
用费马原理证明光的折射定律和反射定律,pdf格式,简单易懂。网络上大部分是要钱的
费马定理学术证明,数学控值得收藏。 X^n + y^n = Z^n n大于3时,该等式没有正整数解。 简洁的命题,证明的费尽,期待费马的巧妙证明。
对于正整数,对于p的正整数,如果p不除a,我们将提供一个直观令人满意的费马结果的几何证明。 这就是费马小定理。 该证明是新颖的,它使用了将着色应用于规则多边形的想法来建立数论结果。 传统上(如果模棱两可)...
费马大定理证明历史过程与科普 费马大定理证明历史过程与科普 费马大定理证明历史过程与科普 费马大定理证明历史过程与科普
提出了一个费马问题的极值计算问题,费马问题已被广泛地运用在许多领域,比如军事、商业等领域。因此,在保证隐私的前提下,设计了一个基于点积协议的费马问题极值计算协议。提出的协议仅调用了6次点积协议,不仅...
费马大定理:介绍一些关于费马大定理的背景和当时的一些数学问题
费马大定理-解开一个古代数学难题的秘密.pdf
费马大定理:一部延续358年荡气回肠的惊险悲怆爱情剧.doc
如名称所说
本文为被称为“费马最后定理”的问题提供了一个简短而新颖的解决方案。 它是在不使用抽象代数元素或二十世纪现代数学其他领域的元素的情况下实现的。 因此,任何数学家或任何熟悉基础数学的人都可以轻松理解它。 ...
《数学女孩2:费马大定理》中每一章针对不同议题进行解说,非常适合对数学感兴趣的初高中生以及成人阅读。 Contents: Chapter 1. 将无限宇宙尽收掌心 Chapter 2. 勾股定理 Chapter 3. 互质 Chapter 4. 反证法 ...
底为 a 的 Miller 素数测试设 n 为一较大的奇数,令 n − 1 = 2rs, r ≥ 1, s 为奇数验证一下 r + 1 个同余式是否成立:若至少
费马原理PPT课件.pptx
费马点与中考试题.doc