0

我可以更快地找到完美数字吗?我试图用数组和另一种算法让它更快,但没有一个让它更快。

public class Perfect{
    static long perfectNumber;
    static long startTime = System.nanoTime();
    static long endTime;
    static long mersenne;

    public static void main(String[] args) {

        long p = 2;
        while (p < 32) {
            if( p % 2 == 0&&p!=2){
                    p++;
            }
            else{
            if (isPrime(p) == true) {

                mersenne = (long) (Math.pow(2, p) - 1);
                if (isPrime(mersenne) == true) {
                    perfectNumber = (long) Math.pow(2, (p - 1)) * mersenne;
                    System.out.println(perfectNumber);
                }
            }
            p++;
        }

    }
        endTime = System.nanoTime();
        System.out.println("Time:   " + (endTime - startTime) + "ns"
                );
    }
    private static boolean isPrime(long testPrime) {


            for (long i = 3; i < Math.sqrt(testPrime); i += 2) {

                if (testPrime % i == 0) {

                    return false;
                }
        }

        return true;
    }
}
4

1 回答 1

0

您可以进行一些小的改进 - 可能没有一个会对运行时间产生任何影响:

  1. 使用p % 2可能会导致除法 -p & 1不会,因此应该快一点。
  2. 您可以轻松地将所有素数预先计算到合理的限制。
  3. Math.pow(2,x)在所有情况下都等效于2 << x,并且可能更快。
  4. 在循环中打印是浪费 - 您应该将所有结果收集在一个列表中并在最后打印它们。

除了那些微不足道且可能过早的优化之外 - 您应该运行计算数百次并在尝试任何优化之前取平均时间。

顺便说一句 - 仅仅因为您正在使用nanotime并不意味着您正在获得纳秒级分辨率 - 远非如此。

还 -

正如维基百科文章指出的那样 - 您可以通过枚举那里提到的常见二进制模式来避免大部分计算:

for ( int i = 0; i < 10; i++ ) {
  long q = ((1 << (i+2)) - 1) << (i+1);
  // Printing BigIntegers in binary is easy.
  BigInteger bq = BigInteger.valueOf(q);
  System.out.println(q+" = "+bq.toString(2));
}

6 = 110
28 = 11100
120 = 1111000
496 = 111110000
2016 = 11111100000
8128 = 1111111000000
32640 = 111111110000000
130816 = 11111111100000000
523776 = 1111111111000000000
2096128 = 111111111110000000000

显然,您仍然需要测试它们,但您不必测试那么多。

另外-如果您想更进一步BigInteger,可以从以下内容开始:

for ( int i = 0; i < 10; i++ ) {
  BigInteger p = BigInteger.ONE.shiftLeft(i+2).subtract(BigInteger.ONE).shiftLeft(i+1);
  System.out.println(p.toString(10)+" = "+p.toString(2));
  //long q = ((1 << (i+2)) - 1) << (i+1);
  //BigInteger bq = BigInteger.valueOf(q);
  //System.out.println("    "+bq.toString(10)+" = "+bq.toString(2));
}
于 2013-12-02T10:14:06.133 回答