Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用BigInteger查找200位素数_Java_Math_Kotlin_Primes_Prime Factoring - Fatal编程技术网

Java 使用BigInteger查找200位素数

Java 使用BigInteger查找200位素数,java,math,kotlin,primes,prime-factoring,Java,Math,Kotlin,Primes,Prime Factoring,一种绝对有效的方法是从0开始,直到找到200位素数。为此,我编写了以下方法: var primeList = arrayListOf(BigInteger("2")) fun findNextPrime(num : BigInteger): BigInteger { val n = num + BigInteger.ONE val sqrt = sqrt(num) for (bigInteger in primeList) { if(bigInteger

一种绝对有效的方法是从0开始,直到找到200位素数。为此,我编写了以下方法:

var primeList = arrayListOf(BigInteger("2"))
fun findNextPrime(num : BigInteger): BigInteger {
    val n = num + BigInteger.ONE
    val sqrt = sqrt(num)
    for (bigInteger in primeList) {
        if(bigInteger > sqrt){
            return n
        }
        if(n % bigInteger == BigInteger.ZERO){
            return findNextPrime(num + BigInteger.ONE)
        }
    }
    return n;
}
我将找到的数字添加到素数表中,只检查小于平方根的数字。虽然这是我能写的最快的算法,但在找到一百万位数后需要很长时间。一百万位数只有7位数。我可能会死到200位数。(即使我的笔记本电脑是i7第8代)。所以我使用的下一件事是:

n = 2 * 3 * 5 *... + 1
n是素数,使用这种方法可以很快达到高位,但没有什么可以保证精确到200位。我得到了198位和201位。但不是200。代码很简单,但我还是发布了:

var all = BigInteger.ONE
primeList.forEach {
   all *= it
}
all++
println(all.toString().length)

1+第一个
n
素数的乘积并不总是素数。你可能误解了它在证明有无穷多素数中的作用。如果
p_1,p_2,…,p_n
是第一个
n
素数,则

p_1 * p_2 * ... * p_n + 1
是素数或包含一个大于任何一个p_i的素数因子,但这与复合数一致。有关更多信息,请参阅上的维基百科文章

在尝试200位的情况下,前92个素数+1的乘积有199位,前93个素数+1的乘积有201位。在这两种情况下,结果都表明它们是复合的。我还没能把199位的数字计算在内,但201位的数字计算在内

509558935064289364432032169616857776489168568369134671296055828054188240764364761921821351373922822013621199759688858354748131233614846920025560717744496960296617420071391914813530238313960697008021211 = 11587 * 43976778723076669062918112506848863078378231498156094873224806080451216083918595142989673890905568483094951217717170825472351016968572272376418461874902646094469441621765074205016849772500275913353
对于这样数量级的数字,获得素数的唯一有效方法是随机生成目标大小的候选数,并测试其素数性(使用类似米勒-拉宾测试的方法)。根据素数定理,200位素数是相对丰富的,所以在实践中你可以很快找到这样一个素数。例如,我使用Miller Rabin编写的Python脚本在不到一秒钟的时间内写出了以下200位素数:

49675218696612399034240799519655205503986657506787162015105425670413948962864456158664793804627084299081036134562339483478437262146378569515417671690110863951848724044479367633926630234074394356492223
编辑时:下面是我用来查找200位素数的Python脚本。这段代码是为我教的一门密码学课编写的,所以我写这段代码是为了便于讨论,而不是为了简洁或高效:

import random

#The following function finds s and d in
#n-1 = 2^s*d with d odd
def findSD(n):
    s = 0
    d = n-1
    while d % 2 == 0:
        s = s + 1
        d = d//2
    return s,d

def checkBase(a,n):
    s,d = findSD(n)
    x = pow(a,d,n)
    if x == 1 or x == n-1:
        return "probable prime"
    else:
        for i in range(s-1):
            x = pow(x,2,n)
            if x == 1:
                return "composite"
            elif x == n-1:
                return "probable prime"
        #if you get to this stage, -1 not reached despite s-1
        #squarings -- so must be composite
        return "composite"

def MSR(n,k):
    #Implements the Miller-Selfridge-Rabin test for primality
    for i in range(k):
        a = random.randint(2,n-2)
        if checkBase(a,n) == "composite":
            return "composite"
    #if you get here n has survived k potential witnesses, so
    return "probable prime"

#The following function is slightly different from the one discussed in class:

def prime(n):
    smallPrimes = [2,3,5,7,11,13,17,19]

    for p in smallPrimes:
        if n == p:
            return True
        elif n % p == 0:
            return False

    if MSR(n,20) == "composite":
        return False
    else:
        return True

def findPrime(maxN):
    while True:
        m = random.randint(1,maxN//2)
        n = 2*m+1
        if prime(n):
            return n

例如,
findprome(10**200)
通常会给您一个200位的素数(尽管可以得到199位或更小的素数)。

在BigInteger类中,有一个方法称为:

isProbablePrime(int)
它使用了我们朋友使用的相同算法:
但它也会用另一种算法检查结果。它的工作原理非常简洁。

btw
all+=all*it
不会计算素数列表的乘积。您可以将代码更改为大整数。kotlin中有序列的概念。你应该调查一下。另外,第200个价格是1217,它不是那么大,所以你可以只使用整数。
那么n是素数
?一般来说,情况并非如此。并非所有的元素都与素数相差1。要得到一个200位长的素数,唯一可行的方法是生成该大小的随机奇数并测试它们的素数性。换句话说,我只是对两个跨越200个数字的原始素数候选人进行了米勒-拉宾测试。这两个数字都是复合数字。一位大学硕士告诉我,3*5*7。。。总是有效。看起来他有点不舒服。谢谢你让我知道。顺便说一句,如果你不喜欢kotlin或java,即使是分享你的python代码也会有帮助:)所以请发出来谢谢。@stevemoretz我添加了代码。3*5*7 ... + 1被用来表示存在任意大的素数,所以如果你只记得这个事实,并且有一段时间没有进行过证明,很容易看出,数字本身不一定是素数的细微之处可能会丢失。很抱歉,你所说的表达式或然素数是什么意思?我们还不确定你最后的意思吗?@stevemoretz Miller-Rabin测试是概率的。它不能证明一个数字是素数,但可以使误报概率任意低(低于运行确定性算法时硬件出错的概率)。谢谢。看起来Miller Rabin已经是本机java中的函数了!我只是不太明白。如果你能解释得再深入一点,减少复杂性,那就太好了。我只是个程序员,不是数学专业的。