使用java的nextprobableprime()来获取previousprobableprime

时间:2013-05-03 14:04:22

标签: java biginteger

我想使用nextProbablePrime()的{​​{1}}方法来获得低于给定数字而不是更高的素数。

是否可以仅使用一次BigInteger电话来获取它?

1 个答案:

答案 0 :(得分:2)

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

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秒。结论,执行时间的差异增加慢于范围大小。

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

这种效率水平足以满足我的需求......也可能适合你。