素数判断算法

素数判断算法
素数判断算法

我发现了筛法的计算公式(最后稿)

我发现了筛法的计算公式 孟庆馀[江苏连云港] 2010年5月 [摘要]: 笔者在探索中,发现了有关素数与合数关系的三条主要规律: 1、区段(区域)性的规律。 2、逐项相除四舍五入的规律。 3、随从数的规律。 根据这三条规律推导出一个公式, 它可以计算出任一已知素数后边紧跟的那个素数和任意大的一个自然数之前共有多少个素数的问题。 这个公式是: m p = 2N -N [ (211p p +311p p -3211p p p ±…±13211-n p p p p Λ)+ ( )1111132131211-±±++-n p p p p p p p p p ΛΛ(-n p 1)]+(1-n ) [关键词]: 筛法公式、逐项相除、四舍五入、区段、随从数。 [正文]: 笔者在多年的探索中,发现了有关素数与合数关系的一些规律,根据这些规律找到了一个可以对埃拉多斯染尼氏(Eratosthenes )筛法进行计算的公式,即“筛法计算公式”(它包括计算素数和计算奇合数两个公式),计算素数的公式也可以称为“素数公式"。给素数找出一个通项表达式,即已知任一素数后边紧跟的那个素数的公式,这是一个缠绕着数学家的世界难题,时至今日都没有解决。笔者的这个公式能较好地解决任一已知素数后边紧跟的那个素数的问题。 一、“筛法计算公式”(用于计算素数) m p = 2N -N [ (211p p +311p p -3211p p p ±…±13211-n p p p p Λ)+ ()1111132131211-±±++-n p p p p p p p p p ΛΛ(-n p 1)]+(1-n ) …(1) 式中m p 为1~N 数列中素数个数;N 为任意大的自然数(2n p ≤N <21+n p ) ;n p p p p ,,,,321K 为素数,其中:1p = 2,2p = 3,3p = 5,…,6p = 13,…;n ≥2 。

素数普遍公式

素数普遍公式 目录[隐藏] 一、引言 二、素数普遍公式 三、素数的个数 四、公式的用途 五、素数普遍公式在认识形成中的作用和意义 思考题 一、引言 二、素数普遍公式 三、素数的个数 四、公式的用途 五、素数普遍公式在认识形成中的作用和意义 思考题 [编辑本段] 一、引言 2000多年前欧几里德在证明素数无穷多时就埋下了寻求素数普遍公式的伏笔 素数普遍公式 ,以布劳维尔为首的直觉主义学派认为:“你没有给出第n个素数是如何构造的,就不能算是好的证明”。2000多年来,数论学最重要的一个任务,就是寻找素数普遍公式,为此,一代又一代数学精英,耗费了巨大的心血,始终未获成功。黎曼曾想用他的ζ函数数的“零点”来逼近素数普遍公式,至今未获成功。也有人反向思考,用素数普遍公式逼近“零点”来解决黎曼猜想。希尔伯特在1900年的国际数学家大会上说:对黎曼公式进行了彻底讨论之后,或许就能够严格解决哥德巴赫问题和孪生素数问题。实际在哲学上,只要有一个明确的定义,就应该有一个公式。 [编辑本段] 二、素数普遍公式

公元前250年同样是古希腊的数学家埃拉托塞尼提出一种筛法: (一)“要得到不大于某个自然数N的所有素数,只要在2---N中将不大于√N的素数的倍数全部划去即可”。 (二)将上面的内容等价转换:“如果N是合数,则它有一个因子d满足1

筛法求素数

筛法求素数 目录 基本思想 C语言实现 pascal实现: 1C++实现: 2python 实现: 基本思想 用筛法求素数的基本思想是:把从1开始的、某一范围内的正整数从小到大顺序排列,1不是素数,首先把它筛掉。剩下的数中选择最小的数是素数,然后去掉它的倍数。依次类推,直到筛子为空时结束。如有: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1不是素数,去掉。剩下的数中2最小,是素数,去掉2的倍数,余下的数是: 3 5 7 9 11 13 15 17 19 21 23 25 27 29 剩下的数中3最小,是素数,去掉3的倍数,如此下去直到所有的数都被筛完,求出的素数为: 2 3 5 7 11 13 17 19 23 29 C语言实现 1、算法一:令A为素数,则A*N(N>1;N为自然数)都不是素数。 #define range 2000 bool IsPrime[range+1]; //set函数确定i是否为素数,结果储存在IsPrime[i]中,此函数在DEV C++中测试通过 void set(bool IsPrime[]) { int i,j; for(i=0;i<=range;++i) IsPrime[i]=true; IsPrime[0]=IsPrime[1]=false; for(i=2;i<=range;++i) { if(IsPrime[i]) { for(j=2*i;j<=range;j+=i) IsPrime[j]=false; } } } 2、 说明:解决这个问题的诀窍是如何安排删除的次序,使得每一个非质数都只被删除一次。中学时学过一个因式分解定理,他说任何一个非质(合)数都可以分解成质数的连乘积。例如,16=4^2,18=2 * 3^2,691488=2^5 * 3^2 * 7^4等。如果把因式分解中最小质数写在最左边,有16=4^2,18=2*9,691488=2^5 * 21609,;换句话说,把合数N写成N=p^k * q,此时q当然是大于p的,因为p是因式分解中最小的质数。由于因式分解的唯一性,任何一个合数N,写成N=p^k * q;的方式也是唯一的。由于q>=p的关系,因此在删除非质数时,如果已知p是质数,可以先删除P^2,p^3,p^4,... ,再删除pq,p^2*q,p^3*q,...,(q是比p大而没有被删除的数),一直到pq>N为止。 因为每个非质数都只被删除一次,可想而知,这个程序的速度一定相当快。依据Gries与Misra的文章,线性的时间,也就是与N成正比的时间就足够了(此时要找出2N的质数)。(摘自《C语言名题精选百则(技巧篇)》,冼镜光编著,机械工业出版社,2005年7月第一版第一次印刷)。代码如下: #include #include using namespace std; int main() { int N; cin>>N; int *Location=new int[N+1]; for(int i=0;i!=N+1;++i) Location[i]=i; Location[1]=0; //筛除部分int p,q,end; end=sqrt((double)N)+1; for(p=2;p!=end;++p) { if(Location[p]) { for(q=p;p*q<=N;++q) { if(Location[q]) { for(int k=p*q;k<=N;k*=p) Location[k]=0; } } } } int m=0; for(int i=1;i!=N+1;++i) { if(Location[i]!=0) { cout<

判断质数的5个C语言程序

判断质数的5个C语言程序(含代码) ——程序优化的重要性 质数 质数是指在一个大于1的自然数中,除了1和它本身之外,无法被其他自然数整除的数。 本文将会带领大家编写计算质数的程序。 质数计算程序(第1版) 判断一个数mo是否为质数的方法就是看它能否被2、3、……、mo-1整除、如果它不能被其中任何一个整数整除,那么这个数就是质数。例如我们要判断13是不是质数,就需要看它能否被下面这11个数整除。 2、3、4、5、6、7、8、9、10、11、12/*通过11次除法计算来判断其是否为质数*/ 因为13无法被其中任何一个数整除,所以可以确定它是质数。 但是对于12来说,并不需要使用2、3、4、5、6、7、8、9、10、11这十个数来判断它是 不是质数。也就是说,12能够被第一个数2整除,所以它就不是质数。 程序代码ver1:(绿色部分) /*30-5-2017*/ /*计算出1000以内的质数*/ #include int main() { inti,no; int counter=0; for(no=2;no<=1000;no++) { for (i=2;i

return 0; } 运算结果: *注意,这个程序的乘除运算次数为78022次。 质数计算程序(第2版) 我们注意到,大于2的所有偶数都不是质数,所以在判断1000以内的质数时可以排除大于2的偶数,可以得到下边的程序: 程序代码ver2:(绿色部分) /*30-5-2017*/ /*计算1000以内的质数(第2版)*/ #include int main() { inti,no; int counter=0; no=2; printf("%d\n",no++); /*2是偶数中唯一的质数,先打印出来*/ for (;no<=1000;no+=2) /*只把奇数作为判断对象,排除大于2的偶数*/ { for (i=2;i

判断某个数是否素数

判断某个数是否素数: 1.定义为一个function函数过程 第一种方法: Function prime(ByVal x As Integer) As Boolean 注1 For i = 2 To x – 1 注2 If x Mod i = 0 Then Exit For Next i If i > x - 1 Then prime = True 注3 End Function 注1:这里注意形参前面有ByVal,不要ByVal也是可以的,为什么? 因为在function中并未改变x的值,所以加不加ByVal都正确 注2:此句也可以这样写:For i = 2 To x/2 或 For i = 2 To sqr(x) 注3:此句也可以这样写:If i > x - 1 Then prime = True Else prime = False 思考:为什么不要Else prime = False 程序运行也是正确的 另外注意此处的条件i > x – 1的实际含义 调用的时候(调用函数时,最好不要用带call关键字的调用方法) If prime(x) then……… 第二种方法: Function prime(ByVal x As Integer) As Boolean Prime=false 注1 For i = 2 To x – 1 If x Mod i = 0 Then Exit Function注2 Next i prime = True 注3 End Function 注1 此句要不要都可以,思考为什么 注2和注3两条语句与第一种方法的区别 调用的时候 If prime(x) then……… 第三种方法: Function prime(ByVal x As Integer) As integer Prime=0 For i = 2 To x – 1 If x Mod i = 0 Then Exit Function Next i prime = 1 End Function 此方法与上述方法的区别 调用的时候 If prime(x)=1 then………

用筛法求出100以内的全部素数

例6、用筛法求出100以内的全部素数,并按每行五个数显示。 【问题分析】 ⑴把2到100的自然数放入a[2]到a[100]中(所放入的数与下标号相同); ⑵在数组元素中,以下标为序,按顺序找到未曾找过的最小素数minp,和它的位置p(即下标号); ⑶从p+1开始,把凡是能被minp整除的各元素值从a数组中划去(筛掉),也就是给该元素值置0; ⑷让p=p+1,重复执行第②、③步骤,直到minp>Trunc(sqrt(N)) 为止; ⑸打印输出a数组中留下来、未被筛掉的各元素值,并按每行五个数显示。 用筛法求素数的过程示意如下(图中用下划线作删去标志): ① 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {置数} ② 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被2整除的数} ③ 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被3整除的数} …… 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {筛去被整除的数} Program Exam53; const N=100; type xx=1 .. N; {自定义子界类型xx(类型名)} Var a: array[xx] of boolean; i,j: integer; Begin Fillchar(a,sizeof(a),true); a[1] := False; for i:=2 to Trunc(sqrt(N)) do if a[I] then for j := 2 to N div I do a[I*j]:= False; t:=0; for i:=2 to N do if a[i] then Begin write(a[ i ]:5); inc(t); if t mod 5=0 then writeln end; End. 【例3】输入十个正整数,把这十个数按由大到小的顺序排列(将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序中的“简单选择排序”是一种较简单的方法) 分析:要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,……;因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它大的,则与之交换,比较结束后,则第一个数已是最大的数。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次大的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次小的数。于是十个数的顺序排列结束。 例如下面对5个进行排序,这个五个数分别为829105。按选择排序方法,过程如

质数的判定

质数的判定 舒云水 课本第3页的例1及例1后面的探究问题是“质数的判定” 问题,它有丰富的数学背景,下面给读者做一个简单介绍﹒质数有无穷多个﹒大约在2300年前欧几里得就证明了存在着无穷多个质数﹒尽管如此,迄今为止还没有发现质数的模型或产生质数的有效公式﹒因而寻找大的质数必须借助计算机一个一个地找﹒寻找大质数是数论研究的重要课题之一﹒目前找到的最大质数是梅森质数1 243112609 ,它有12978189位数,如果用普通字号将这个巨数连续写下来,它的长度可超过50公里! 读者可能会产生一个疑问:找大质数有什么用?现在最好的密码是用质数制造的,极难破译﹒ 人们一直在寻找检验一个数是否为质数的方法,最近一些年有了巨大进步﹒你或许会说,检验质数有什么难?确实,看一个数是不是质数,有一种非常自然而直接的方法,这就是我们常用的试除法,即课本例1所用的算法﹒这一方法对检验不太大的数是挺实用的﹒但若数字太大,它就变得十分笨拙﹒假设你在一个快速计算机上实用高效的程序进行试除﹒对于一个10位数字的数,运行程序几乎瞬间就能完成﹒对于一个20位的数就麻烦一点了,需要两个小时﹒对于一个50位的数,则需要100亿年﹒这已经大得不可想象﹒前面讲过最好的密码是用质数制造的,它是用介于60位到100位之间的两个质数制造的,这种计算正是制造这种密码的需要﹒当今庞大的国际数

据通讯网络能安全运行,就得益于这种密码﹒ 如何确定一个100位的数是否为质数呢?数学家做了许多努力,在1980年左右找到了目前可用的最好方法﹒数学家阿德勒曼,鲁梅利,科恩和伦斯特拉研究出一种非常复杂的方法﹒现在以他们的名字的第一个字母命名为ARCL检验法﹒在上面提到的那类计算机上进行ARCL检验,对20位的数只需10秒钟,对50位的数用15秒,100位的数用40秒﹒如果要检查1000位的数,一个星期也就够了﹒可以相信,随着人们对质数的判定算法的研究不断深入及计算机技术的迅猛发展,我们会找到更好更快地检验一个大数是否为质数的方法,发现更多更大的质数﹒

C语言素数的几种判断方法

#include #include main() { int i,n; printf("请输入一个数:"); scanf("%d",&n); for(i=2;i=n) printf("素数!"); printf("\n"); } /*main() { int i,n,m; printf("请输入一个整数:"); scanf("%d",&m); n=(int)sqrt(m); for(i=2;i<=n;i++) if(m%i==0) break; if(i>n) printf("素数!\n"); else printf("不是素数!"); }*/ /*int p(int m) { int i,n=sqrt(m); for(i=2;i<=n;i++) if(m%i==0) break; if(i>n) return 1; else return 0; } main() {

int m; for(m=1;m<=10;m++) { if(p(m)) printf("%d ",m); } printf("\n"); }*/ //3-100间所素数。 /*main() { int i,n; for(n=3;n<=100;n++) { for(i=2;i<=n-1;i=i+1) if(n%i==0) break; if(i>=n) printf("%d\t",n); } }*/ /*main() { int i,m,j; for(i=2;i<=10;i++) { m=sqrt(i); for(j=2;j<=m;j++) { if(j%m==0) break; if (j>m) //加上这句,如果检查所有的j全部不能整除m,循环结束后,j一定大于m,这时的i才是素数 printf("%d",i); } } } /* void main() { int i,j,n=0,xx[10]; for(i=1;i<10;i++)

素数的几种判断方法和实现

PS:本来没有决心把这个东西写完的,结果早上写到一半,出去吃个饭,没保存,回来手一抖直接关掉了,好不容易写了一大半了,只能重新写了,坑爹啊,但就是这个插曲,本来还没有决心的我,一下子却坚定了信念,一点要把这个东西写完。就这样开始吧 BY:Lee 下面,我们重新开始 ═══════════════════════════════════════════ 如何判断一个数是否是素数呢 ═══════════════════════════════════════════也许你会认为这是一个简单的问题,但事实上,世界上任何一个问题,都没有你想象中的那么简单1 + 1 是否等于2 ,这便是一个简单而又复杂的问题,呵呵。 突然想把这个东西换一种风格来写了,就这样扯淡扯下去吧。扯的时候文章中多少有内容来自于网络,没有侵权的意思,如果作者看到还请见谅。 ═══════════════════════════════════════════下面正式进入正题 ═══════════════════════════════════════════ 一、朴素判断素数 ═══════════════════════════════════════════1. 这种方法被誉为笨蛋的做法: 一个数去除以比它的一半还要大的数,一定除不尽的,这还用判断吗?? 很容易发现的,这种方法判断素数,对于一个整数n,需要n-2 次判断,时间复杂度是O(n)在n非常大或者测试量很大的时候,这种笨蛋做法肯定是不可取的。

2. 改进一下下小学生的做法: 3. 再改进一下聪明的小学生的做法 对于一个小于n的整数X,如果n不能整除X,则n必定不能整除n/X。反之相同一个明显的优化,就是只要从2枚举到√n 即可。 因为在判断2的同时也判断了n/2。到√n时就把2到n-1都判断过了。 在这里,这个聪明的小学生还用了i*i <= n 来代替sqrt(n), 这里是避免了调用函数sqrt(),其消耗时间很大, 特别是在大量数据测试的时候消耗很明显。 这个算法的时间复杂度,与最前面的笨蛋做法就好多了, 不过这里好像用sqrt()也没问题啊,,,,这个就不太清楚了。 但是做一个测试发现,如果是这样额话,每一次判断都要计算i*i,

素数的线性筛法

素数的线性筛法 //整体思想是从自然数 2 开始与所有之前已经确定的素数相乘后的数标记为合数就能把素数一个不漏地找出来 #include #include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 1 ) #define FOR(i,s,t) for(int i=(s); i<(t); i++) #define FORD(i,s,t) for(int i=(s-1); i>=t; i--) #define BUG puts("here!!!") #define STOP system("pause") #define file_r(x) freopen(x, "r", stdin) #define file_w(x) freopen(x, "w", stdout) using namespace std; const int SULEN = 1000000; bool flag[SULEN+1];// 是否为素数 int prime[1000001];// 存储的素数 int sum[SULEN+1];//n 的所有质因子的和 void xianxingshai(void) { int count,i,j; fill( flag,flag+SULEN,true ); // 初始化假设每个都为素数 fill( sum ,sum +SULEN, 0 ); //初始化质因子和为0 flag[0] = flag[1] = false; //0 和 1 不是素数 for( count = 0, i = 2; i <= SULEN; i++ )// 从 2 开始判断是否为素数 { if( flag[i] ) // 如果是素数 { prime[count++] = i;sum[i] = i; //将值传到prime 数组中 } for( j = 0; j < count && i*prime[j] <= SULEN; j++ ) // 将包含该质因数的合数都 标为 false

素数判断程序测试范例

问题描述:键盘输入m和n(10 #include using namespace std; int main() { int m,n,i; static int k=0; cout<<"输入m,m(其中10>m>>n; while(m<=10||m>=n||n>2000) { cout<<"输入数据有误,请再次输入:"<>m>>n; } for(i=m;i<=n;i++) { int x=(int)sqrt((double)i); for(int j=2;j<=x;j++) { if(i%j==0) { break; } else if(j==x) { cout<

一.控制流测试1、控制流图如下:

2、根据以上控制流图: 因为控制流的1-2-3-2部分为用户输入的m,n的重复赋值过程,与输入数据密切相关且每次取值不同,关系到控制流测试,所以将此独立出来:以为节点“2”的复合谓词为或的关系,全为false时只有一种情况,而为true 时有7种情况,对“2”的复合谓词(m<=10||m>=n||n>2000)为真假时其表1如下: 设A:m<=10; B:m>=n; C:n>2000 但是对于节点“2”的情况,并非所有可能都会取到,因为当A为真时,就不会执行B,依此,生成下表2: 根据表2,得出此部分的取值及路径为:

判断一个数是质数还是合数的方法

判断一个数是质数还是合数的方法 单位:平川区黄峤教管中心双铺中心小学张彦娟 一、质数和合数的意义: 质数:一个数只有1和它本身两个因数,这个数叫作质数。(除2以外所有的质数都是奇数。) 备注: 1、最小的质数是2。 2、既是偶数又是质数的数是2。 3、两个质数相乘的积一定是合数。 合数:一个数除了1和它本身以外还有其他的因数,这个数叫作合数。 备注: 1、最小的合数是4。 2、最大的一位合数是9。 3、1既不是质数,也不是合数。 二、判断一个数是质数还是合数有两种方法: 方法一:⑴判断一个数是质数还是合数需要看这个数的因数的个数,只有2个因数的数一定是质数,有3个或3个以上因数的数是合数。 ⑵个位上是0,2,4,6,8和5的数(除了0,2和5)一定不是质数,质数个位上的数字只能是1,3,7和9。 方法二:判断一个自然数是不是质数,可以用所有比它小的质数

从小到大依次去除它,除到商比除数小,而且还有余数,它就是质数,否则不是质数。 三、问题解析: 下面哪些数是合数?哪些数是质数? 2 25 9 21 31 91 57 42 1、方法解析:因为除了1和它本身以外还有其他的因数的数是合数,所以先根据“2,5和3的倍数特征”来判断这些数除了1和它本身两个因数以外是否有因数2,5,3,如果有就为合数。 2和42有因数2,但2只有1和2两个因数,所以2是质数,42是合数。9,21,57有因数3,它们都是合数。25有因数5,也是合数。91有因数7,是合数。只有31除了1和它本身之外再没有其他的因数,所以31是质数。 2、解答:25,9,21,91,57,42是合数,2,31是质数。 四、100以内的质数: 100以内的质数有:2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,共25个。

线性筛法求素数的原理与实现

何为线性筛法,顾名思义,就是在线性时间内(也就是O(n))用筛选的方法把素数找出来的一种算法,没用过线性筛素数法的人可能会奇怪,用遍历取余判定素数不是也是线性时间的吗,没错,但是确切的说线性筛法并不是判定素数的,而是在线性时间内求出一个素数表,需要判定是否是素数的时候只要看该数是否在表内就可以瞬间知道是不是素数。 比如想求10000以内的素数,定义表int a[10000],进行线性筛选后,a[n]的值就代表n是不是素数,a[n]如果是1,就代表n是素数,a[n]如果是0,就代表n不是素数,这就是查表。再判定其他的素数也是一样,不用再做任何计算。 而如果用遍历取余,那么每判定一个数都要从头开始再遍历一遍,而线性筛法只在开始一次性运算完,以后只要查表即可,查表通常只需要1条语句。所以如果你的程序从始至终只需要判定那么几次素数那么用遍历取余即可,但是如果需要多次判定素数,而且这个数还不是很小的话,那么线性筛法就会体现出巨大的优越性来。 线性筛法的核心原理就是一句话:每个合数必有一个最大因子(不包括它本身),用这个因子把合数筛掉,还有另一种说法(每个合数必有一个最小素因子,用这个因子筛掉合数,其实都一样,但是我觉得这种方法不太容易说明,这种方法我会在最后给出简略说明)。这个很容易证明:这个小学就知道合数一定有因子,既然是几个数,就一定有最大的一个。最大因子是唯一的,所以合数只会被它自己唯一的因子筛掉一次,把所有合数筛掉后剩下的就全是素数了。 先假设一个数i,一个合数t,i是t最大的因数,t显然可能并不唯一(例如30和45的最大因数都是15)。那么如何通过i知道t呢,t必然等于i乘以一个比i小的素数。先来说这个数为什么一定要比i小,这很显然,如果是i乘上一个比它大的素数,那么i显然不能是t 最大的因子。再来说为什么要是素数,因为如果乘上一个合数,我们知道合数一定可以被分解成几个素数相乘的结果,如果乘上的这个合数x=p1*p2*……,那么 t = i * x = i * p1 * p2……很显然p1* i也是一个因数,而且大于i。所以必须乘上一个素数。 比i小的素数一定有不少,那么该乘哪一个呢,既然t不唯一,那么是不是都乘一遍呢?很显然不行,虽然t不唯一,但全乘一遍很显然筛掉的数的数量远远超过合数的数量。我们先给出结论: 任意一个数i = p1*p2*……*pn,p1、p2、……pn都是素数,p1是其中最小的素数, 设T 为i * M的积(显然T就成了一个合数),也就是T = i * M,(M是素数,并且M<=p1),那么T的最大的因数就是i。 是的,乘上的数要小于等于i最小的质因数。

ACM 筛素数总结

【总结】关于求素数的说【两种筛法】 (学习小结,请无视) 素数大家都很熟了,不多说了,这里只想说一下求素数。 当然先是唯一素因子分解定理:合数a仅能以一种方式,写成如下的乘积形式:a=p1e1p2e2…prer 其中pi为素数,p1sqrt(n)时筛中剩下的数就已经都是素数了。 //用数组prime[MAXN]记录是否为素数; //prime[i]为0表示i为素数,否则为合数 int prime[MAXN]={0}; for(i=2;i*i<=n;i++) { if(prime[i]==0) { for(j=i+i;j<=n;j+=i) prime[j]=1; }

孪生素数筛法

孪生素数筛法 齐宸 首先研究一下个位为3的合数。 要想两数相乘的结果个位为3,这两数字的个位有且只有两种组合1、3或7、9。自然数(10k+1)乘以自然数(10i+3),可以利用初中数学将其转化为10[(10i+3)k+i]+3形式。去个位后转换为(10i+3)k+i。 同法可得个位为1、3、7、9全部无个位合数公式,结果如下: 个位为1:(10i+1)k+i、(10i+3)k+7i+2、(10i+9)k+9i+8 个位为3:(10i+3)k+i、(10i+7)k+9i+6 个位为7:(10i+7)k+i、(10i+3)k+9i+2 个位为9:(10i+9)k+i、(10i+3)k+3i、(10i+7)k+7i+4 这里的关键是去掉个位。 显然个位为1的无个位合数公式可以求得所有个位为1的合数,计算结果中没有的数字必是个位为1的素数,也就说可以筛出所有个位为1的素数。这实际上就是个位为1的素数筛法。 同样个位1和个位为3的5组无个位合数公式合用,可以计算得到所有个位为1和个位为3的合数,也就等同于得到了任意一个自然数内所有个位为1和3的非孪生素数。而剩余数字全部是孪生素数。此时的非孪生素数与孪生素数不是2个数字,全部是一个数字。比如个位1和个位为3的5组无个位合数公式合用能计算出10以下9个数字中的6个数字,分别是2、3、5、6、8、9,这些无个位数字分别填上个位数字1、3后变成两个数字,如2变成21-23显然这组不是孪生素数。同样,31-33、51-53、61-63、81-83、91-93也不是孪生素数。而计算结果中没有的数字1、4、7,这3个数字填上个位1和3后分别变成了11-13、41-43、71-73,全部是孪生素数。这种方法实质上就是孪生素数筛法。当然仅是个位为1和3的这类孪生素数。(17-19和29-31这样类型的孪生素数变换公式后也可求出)。 这里有三个新观点: 1、孪生素数可以用一个数字指代。 如用1指代孪生素数11-13,用4指代孪生素数41-43。相反的如2、3是非孪生素,分别对应的是21-23和31-33。 2、孪生素数存在补集:非孪生素数。

密码学实验-素数判别

实验报告 实验七、素数判别 实验目的: 1、熟练掌握根据定义判定一个整数n是否为素数的方法及实现。 2、体会素数判定的时效性。 实验内容: 1、写出根据定义判定一个整数n是否为素数的算法及其实现。 2、判定101、10001、10000001、10000000000001是否为素数,并记录执行时间。 实验结果: 如果某个自然数n是素数,那么可能存在这样的情况—在2~n/2范围内没有一个自然数k能够整除n。所以,如果要判断自然数n是否为一个素数,只需要让n不断的去除以从2开始的,到n/2结束的整数k,这是一个反复执行的操作。如果在这个范围内的数没有一个k能够整除n,就说明n是一个素数。反之,只需要存在一个k能够整除n,就说明n不是一个素数。下面是我们对这个算法的分析: (1)首先输入一个需要判定的自然数n; (2)然后,将作为质数标志的字符串变量str的值设置为“是质数”; (3)接着,我们设置一个除数变量,同时也是一个计数变量k,将其初值设置为2; (4)使用第一个判断框,设置循环的条件为“k<=n/2”,因为除数变量k的最大取值不可能超过n/2; (5)使用第二个判断框,设置分支条件“n Mod k = 0”来判定自然数n能否被当前的除数变量k整除,如果条件不成立,则让除数变量k加1,然后返回到循环条件的判断框入口处,否则将质数标记字符串变量的值赋值为“不是质数”,再强行退出循环结构,输出变量str 的值,算法结束; (6)当正常退出循环结构后,也同样要输出质数标记字符串变量str的值,算法结束。对于本次实验,我们首先要把二进制转换成十进制素再利用上述算法判断是否为素数。 运行程序如下所示: #include #include

用筛法求素数

输出素数表,方法之一就是舍弃空间,换取时间,也就是用一个大数组来存放每一个数是不是素数。这样用筛法求素,大大的减少了时间。下面的筛法求素程序求(不输出,即不定义OUT)1亿以内的素数只需要十几秒的时间,远小于输出所需的时间。 这个程序用一个char数组来存放每一个奇数是不是素数的信息。一个char是一个字节8位,存放8个数。 Program prime_char.cpp: #include #include #include //#define DEBUG #define OUT using namespace std; //常量定义 const long MAX=100000000; const long CHAR_MAX=int(MAX/16+1); const char byt[8]={128,64,32,16,8,4,2,1}; // 变量定义 /********************************** prime saves whether n is a prime the value of n is like: prime[0]: 3, 5, 7, 9,11,13,15,17 prime[1]:19,21,23,25,27,29,31,33 **********************************/ unsigned char prime[CHAR_MAX]; // 函数声明 inline bool isprime(long); inline void setcomposite(long); void primeinitiate(void); void out(long); //函数定义 /**************************************** *Function main * ****************************************/ int main() { #ifdef DEBUG test(); #else long n,m; primeinitiate(); n=5; while(n*n<=MAX) { if (isprime(n))

黎曼假设(2)素数个数公式

黎曼假设(2)素数个数公式《黎曼假设》(2)突破性解答 素数分布规则③——素数个数公式 千禧年世界数学难题之四解答 1900年希尔伯特23个问题第8题 世界数学难题解答 作者:中国数论研究者 江西景德镇 乐平林登发 (经济师) 邮箱:2208831455@https://www.360docs.net/doc/1816821665.html, 2015.7.8

㈠前言 随着《黎曼假设》素数分布被级数筛法突破性解答,《孪生素数猜想》素数对被序号筛法突破性解答,在数论史上还有关于素数无限发展,无限延伸从0至∞的发展趋势,它们的数量计算还是渺茫,难以捉摸。 古今很多学者創造过一些计算素数个数公式,不是属于数理逻辑推导出来的,而是捕风捉影硬套产生的,所以很多公式一用就失效,目前世界上还沒有素数个数精确公式,那怕局部区域使用的也沒有,大家都在渴望,期盼着…… 当前是万民创业,万众创新时代,陷入僵局的素数分布问题应运而生,应运而解,上可顺乎天意,下和谐接地气,素数分布个数公式要出世了,古老数论将有突破性进展。 ㈡基础理论引导 自然数是素数及素数变換形态模式共同产生的混合体,六进制1633规则级数筛法揭露自然数中素数分布规则,只有在阳奇数6N+1和在阴奇数6N-1中有素数存在。 阳奇数中的素数叫阳素数,阴奇数中的素数叫阴素数,从此知道素数也有阴阳之分。 由六进制中6分解:6=1X2x3中得到1,2,3,是0号原始素数。 因此素数理念革命性改变了,素数有三种:原始素数,阳素数,阴素数。因此 素數数量精确公式: ∑全体素数分布数量个数 =∑原始素数+∑阳素数+∑阴素数。 后二种统称普通素数,1是先天性原始素数。 在阳奇数中除阳素數以外,还有阳复合“积”合数,可以用十字街规则把它筛选出来。同样在阴奇数除阴素数以外,还有阴复合“积”合数,也可以用十字街规则把它筛选出来。 这些复合“积”合数在相对区域来说数量是变化的,是动态的。随区域变化而变化,分布数量十分不均匀。所以在无数次探索中釆取以动制动求解,才符合数理逻辑。只有转换思维方法,简单而直接的答案就可能是最合理可行的。 ㈢主题: 素数分布规则③——素数个数公式 从铁路规则双轨数中结构分析: ①原始素数即0号素数1,2,3,共三个。

相关文档
最新文档