我正在尝试在Java中生成大的素数。我使用BigIntegers。这是我在数组中生成和存储10个素数的代码。
public static void primeGenerator() {
BigInteger[] primeList = new BigInteger[10];
BigInteger startLine = new BigInteger("10");
int startPower = 6;
BigInteger endLine = new BigInteger("10");
int endPower = 9;
int j = 0;
for (BigInteger i = fastExp(startLine,startPower);
i.compareTo(fastExp(endLine,endPower)) <= 0;
i = i.add(BigInteger.ONE)) {
if (checkPrimeFermat(i) == true && j < 10) {
primeList[j] = i;
j++;
}
}
System.out.println(primeList[0]);
System.out.println(primeList[1]);
System.out.println(primeList[2]);
System.out.println(primeList[3]);
System.out.println(primeList[4]);
System.out.println(primeList[5]);
System.out.println(primeList[6]);
System.out.println(primeList[7]);
System.out.println(primeList[8]);
System.out.println(primeList[9]);
}
我编写了自己的fastExp函数来更快地生成数字。这是我的其他功能。
public static BigInteger getRandomFermatBase(BigInteger n)
{
Random rand = new Random();
while (true)
{
BigInteger a = new BigInteger (n.bitLength(), rand);
if (BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0)
{
return a;
}
}
}
public static boolean checkPrimeFermat(BigInteger n)
{
if (n.equals(BigInteger.ONE))
return false;
for (int i = 0; i < 10; i++)
{
BigInteger a = getRandomFermatBase(n);
a = a.modPow(n.subtract(BigInteger.ONE), n);
if (!a.equals(BigInteger.ONE))
return false;
}
return true;
}
public static void main(String[] args) throws IOException
{
primeGenerator();
}
public static BigInteger fastExp (BigInteger x, int n){
BigInteger result=x;
int pow2=powof2leN(n);
int residue= n-pow2;
for(int i=1; i<pow2 ; i=i*2){
result=result.multiply(result);
}
for(int i=0 ; i<residue; i++){
result=result.multiply(x);
}
return result;
}
private static int powof2leN(int n) {
for(int i=1; i<=n; i=i*2){
if(i*2>2)
return 1;
}
return 0;
}
}
所以问题是当我尝试使用小数字(例如startPower = 3,endPower = 5)时,它会生成并打印素数。但是,当我尝试使用大数字(例如startPower = 5,endPower = 7)时,它不会生成任何内容。如何改进我的代码以处理大量数据?
谢谢
答案 0 :(得分:7)
首先,我想指出你没有写这段代码。你偷了它from here并声称你写了它,这是非常不道德的。
代码是正确的。这很慢。随着功率的增加,代码需要越来越长的时间。发生这种情况有两个原因:
Fermat测试增长如O(k×log2n×log log n×log log log n)。 BigInteger的加法和减法像O(n)一样增长。显然,BigInteger正在减慢你的速度。
以下是您的代码的配置文件,其功率设置为5到7。
如果您希望代码生成越来越大的素数,您应该专注于减少在BigIntegers上执行的操作数量。这是一个这样的改进:
n.subtract(BigInteger.ONE)
循环之外取for
。结果不需要多次计算。进一步的建议必须来自Mathematics Stack Exchange上的数学人员。
答案 1 :(得分:0)
这是一个更简单的寻找大质数的解决方案 -
BigInteger big = new BigInteger("9001");//or whatever big number you want to start with
BigInteger[] primes = new BigInteger[10];
for(int i=0;i<10;i++){
primes[i]=big=big.nextProbablePrime();
}
它有一些限制here,但根据您的代码,它应该绰绰有余。
答案 2 :(得分:0)
您可以使用BigInteger(int bitLength, int certainty, Random rnd)
构造函数
BigInteger b= new BigInteger(20, 1, new Random());
它将为您生成素数。 bitLength
指定您在BigInteger中需要的位数,certainity
指定您希望BigInteger成为素数的确定性。