使用java的nextprobableprime()来获取previousprobableprime

我想使用BigInteger的nextProbablePrime()方法来获得低于给定数字而不是更高的素数.

是否可以使用一个nextProbablePrime调用来获取它?

最佳答案 我不知道是否可以使用nextProbablePrime方法(在一次调用中).但是,我只需要一个previousProbablePrime方法,并且我想出了以下使用BigInteger API中的isProbablePrime方法的方法:

public static BigInteger previousProbablePrime(BigInteger val) {
    // To achieve the same degree of certainty as the nextProbablePrime 
    // method, use x = 100 --> 2^(-100) == (0.5)^100.
    int certainty = 100;
    do {
        val = val.subtract(BigInteger.ONE);
    } while (!val.isProbablePrime(certainty));
    return val;
}

我设置以下测试只是为了比较nextProbablePrime方法的速度(和准确性):

private static void testPreviousProbablePrime() {
    BigInteger min = BigInteger.ONE; // exclusive
    BigInteger max = BigInteger.valueOf(1000000); // exclusive
    BigInteger val;

    // Create a list of prime numbers in the range given by min and max 
    // using previousProbablePrime method.
    ArrayList<BigInteger> listPrev = new ArrayList<BigInteger>();
    Stopwatch sw = new Stopwatch();
    sw.start();

    val = BigIntegerUtils.previousProbablePrime(max);
    while (val.compareTo(min) > 0) {
        listPrev.add(val);
        val = BigIntegerUtils.previousProbablePrime(val);
    }
    sw.stop();
    System.out.println("listPrev = " + listPrev.toString());
    System.out.println("number of items in list = " + listPrev.size());
    System.out.println("previousProbablePrime time = " + sw.getHrMinSecMsElapsed());

    System.out.println();

    // Create a list of prime numbers in the range given by min and max 
    // using nextProbablePrime method.
    ArrayList<BigInteger> listNext = new ArrayList<BigInteger>();
    sw.reset();
    sw.start();

    val = min.nextProbablePrime();
    while (val.compareTo(max) < 0) {
        listNext.add(val);
        val = val.nextProbablePrime();
    }
    sw.stop();
    System.out.println("listNext = " + listNext.toString());
    System.out.println("number of items in list = " + listNext.size());
    System.out.println("nextProbablePrime time = " + sw.getHrMinSecMsElapsed());

    System.out.println();

    // Compare the two lists.
    boolean identical = true;
    int lastIndex = listPrev.size() - 1;
    for (int i = 0; i <= lastIndex; i++) {
        int j = lastIndex - i;
        if (listPrev.get(j).compareTo(listNext.get(i)) != 0) {
            identical = false;
            break;
        }
    }
    System.out.println("Lists are identical?  " + identical);
}

Stopwatch类只是一个跟踪执行时间的基本自定义类,因此修改这些部分以适合您可能具有的类.

我测试了范围从1到10000,100000和1000000. previousProbablePrime方法在所有三个测试中执行时间更长.然而,似乎执行时间的差异仅随着范围大小每增加10倍而适度增加.对于10000,previousProbablePrime在不到一秒的时间内执行,而nextProbablePrime在大约200毫秒内执行,差异大约为700或800毫秒.对于1000000,差异仅为大约2秒,即使执行时间分别为9秒和7秒.结论,执行时间的差异增加慢于范围大小.

在所有测试中,两个列表包含相同的素数集.

这种效率水平足以满足我的需求……也可能对你有用.

点赞