Fortran 95:素数测试用超大数

Fortran 95:素数测试用超大数,fortran,bigdata,primes,gfortran,fortran95,Fortran,Bigdata,Primes,Gfortran,Fortran95,我对Fortran还很陌生,因为我是在两天前开始学习它的。我开始学习Fortran是因为我开始学习素数,我用python编写了一个程序,速度非常快,它可以在0.1秒内确定123098237是素数。 令人印象深刻,我知道。 不令人印象深刻的是,当我试图找出(2^127)-1或170141183460469231731687303715884105727(顺便说一下)是质数时。程序运行了很长时间,结果我不得不停止它。 所以,我开始寻找一些更快的语言来编写它,所以我用C编写了这个程序。 速度更快,但超

我对Fortran还很陌生,因为我是在两天前开始学习它的。我开始学习Fortran是因为我开始学习素数,我用python编写了一个程序,速度非常快,它可以在0.1秒内确定123098237是素数。 令人印象深刻,我知道。 不令人印象深刻的是,当我试图找出(2^127)-1或170141183460469231731687303715884105727(顺便说一下)是质数时。程序运行了很长时间,结果我不得不停止它。 所以,我开始寻找一些更快的语言来编写它,所以我用C编写了这个程序。 速度更快,但超大素数的问题开始发挥作用。 我想看看是否有解决办法,但后来我从小道消息中得知,如果你用数字编程,Fortran是最快、最好的方法。我模模糊糊地记得我继父大学时的Fortran 77课本,但它们对我来说基本上没用,因为它们谈论的是如何使用穿孔卡片。于是,我上网,获得了Ubuntu 12.04 x86的gfortran,获得了一些PDF,并开始学习。在你知道之前,我做了一个程序,接收输入,测试素数,并且成功了! 但是,同样的老问题出现了,这个数字太大了。
那么,我如何用Fortran处理像这样的大数字呢?

Fortran和许多其他编译语言一样,不提供如此大的整数或开箱即用的运算。一个最新的编译器应该提供一个18位小数的整数,但不能超过18位

如果你想用Fortran语言编程,那么对于这样大的整数,数据类型和运算可以使用你最喜欢的搜索引擎,比如Fortran多重精度。你甚至可以在这里搜索相关的问题和答案

如果你想研究如此大的整数的数学问题,请使用Python;您将很难自己编写与多精度算术运算速度相匹配的软件。Python需要很长时间来确定大数的素性的原因之一是,它需要一个程序,用任何语言编写的任何程序,很长时间来确定大数的素性。如果您仔细研究,您可能会发现相关的Python例程实际上调用了用C或类似的低级语言编写的代码。如果您愿意,可以研究素性测试的计算复杂性这一主题


我并不是说您无法编写性能优于Python内部函数的代码,只是您会发现这是一个挑战。

Fortran与许多其他编译语言一样,不提供如此大的整数或开箱即用的运算。一个最新的编译器应该提供一个18位小数的整数,但不能超过18位

如果你想用Fortran语言编程,那么对于这样大的整数,数据类型和运算可以使用你最喜欢的搜索引擎,比如Fortran多重精度。你甚至可以在这里搜索相关的问题和答案

如果你想研究如此大的整数的数学问题,请使用Python;您将很难自己编写与多精度算术运算速度相匹配的软件。Python需要很长时间来确定大数的素性的原因之一是,它需要一个程序,用任何语言编写的任何程序,很长时间来确定大数的素性。如果您仔细研究,您可能会发现相关的Python例程实际上调用了用C或类似的低级语言编写的代码。如果您愿意,可以研究素性测试的计算复杂性这一主题


我并不是说您无法编写性能优于Python内部函数的代码,只是您会发现这是一个挑战。

大多数语言都提供了某些标准的内部类型,这些类型足以解决标准的科学和工程问题。计算桥梁梁的厚度或规划航天器轨道不需要80位数字。很难达到那样的准确度。在Fortran中,如果您想进行额外精度的计算(例如,对于数论),您需要查找扩充该语言的库,例如mpfun90 at或fmlib at,大多数语言都提供某些标准的内在类型,这些类型完全足以解决标准的科学和工程问题。计算桥梁梁的厚度或规划航天器轨道不需要80位数字。很难达到那样的准确度。在Fortran中,如果您想进行额外精度的计算(例如,对于数论),您需要查找扩充该语言的库,例如mpfun90 at或fmlib at,我猜您的算法是试用除法。如果这是真的,你需要一个更好的算法;实现语言并不重要

Miller-Rabin素性测试的伪代码如下所示。这是概率性的,但您可以通过增加k参数(最大值约为k=25)来降低出错的几率:

函数isPrime(n,k=5)
如果n<2,则返回False
对于[2,3,5,7,11,13,17,19,23,29]中的p
如果n%p==0,则返回n==p
s、 d=0,n-1
而d%2==0
s、 d=s+1,d/2
对于从0到k的i
x=powerMod(randint(2,n-1),d,n)
如果x==1或x==n-1,则下一个i
对于从1到s的r
x=(x*x)%n
如果x==1,则返回False
如果x==n-1,则下一个i
返回错误
返回真值
我将把它留给你翻译成Fortran或其他语言;如果你是用C语言编程,有一个叫做GMP的库,它经常被用来处理非常大的数字,上面显示的函数就是建立在这个库中的。它非常快;数百位数的偶数应归类为素数或复合almos
function isPrime(n, k=5)
    if n < 2 then return False
    for p in [2,3,5,7,11,13,17,19,23,29]
        if n % p == 0 then return n == p
    s, d = 0, n-1
    while d % 2 == 0
        s, d = s+1, d/2
    for i from 0 to k
        x = powerMod(randint(2, n-1), d, n)
        if x == 1 or x == n-1 then next i
        for r from 1 to s
            x = (x * x) % n
            if x == 1 then return False
            if x == n-1 then next i
        return False
    return True