【问题标题】:How can I turn this code from long into BigInteger如何将此代码从 long 转换为 BigInteger
【发布时间】:2019-10-05 13:10:06
【问题描述】:

这是一个获取素数的代码,我已经尽可能地提高了它的效率,但问题是我不能将它转换为 BigInteger,只要不能保存那么多信息;这里是代码:

public class p3{
    static long perfectNumber;
    static long mersenne;

    public static void main(String[] args) {
        long p = 2;
        while (true) {
            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+=1;
            }
        }
    }
    private static boolean isPrime(long testPrime) {
        for (long i = 3; i < Math.sqrt(testPrime); i += 2) {
            if (testPrime % i == 0) {
                    return false;
            }
        }
        return true;
    }
}

【问题讨论】:

  • 您遇到了什么问题?
  • 你看过它的文档了吗? BigInteger
  • 首先问题不是那么长,无法保存足够的信息。它可以容纳19位数字,超过100,000万亿。没有足够的时间使用您的算法甚至筛子来计算这种数量级的素数。但是,使用BigInteger 将让您使用复杂的isProbablePrime 方法。因此,请阅读建议的文档并进行简单的更改。
  • @Goion 我需要将其转换为 BigInteger,只要对于完美数字来说还不够
  • 注意WJS写的。在p 大于单个字节之前,您的isPrime() 方法将永远持续下去,更不用说长了。已知最大的梅森素数是 p = 82,589,933。

标签: java biginteger perfect-numbers


【解决方案1】:

我尝试使用 BigInteger,但代码不起作用,因为我无法使用 带 pow 的 BigInteger 指数

你不需要。指数不需要像梅森素数和完美数一样大。他们可以有自己独立的isPrime() 测试。实际上,它们需要是int,而不是long,才能满足BigInteger.pow()

以下是您要求的,但可能不是您想要的。由于时间限制,我怀疑您是否会在原始代码之外再获得一个完美的数字,这就是@WJS 将您推向不同方向的原因。

import java.math.BigInteger; 

public class p3 {
    static BigInteger TWO = new BigInteger("2");
    static BigInteger THREE = new BigInteger("3");

    public static void main(String[] args) {
        int p = 2;

        while (true) {
            if (isPrime(p)) {
                BigInteger mersenne = TWO.pow(p).subtract(BigInteger.ONE);

                if (isPrime(mersenne)) {
                    System.out.println(TWO.pow(p - 1).multiply(mersenne));
                }
            }

            p += (p == 2) ? 1 : 2;
        }
    }

    private static boolean isPrime(BigInteger number) {
        if (number.mod(TWO).equals(BigInteger.ZERO)) {
            return number.equals(TWO);
        }

        for (BigInteger i = THREE; number.compareTo(i.multiply(i)) >= 0; i = i.add(TWO)) {
            if (number.mod(i).equals(BigInteger.ZERO)) {
                return false;
            }
        }

        return true;
    }

    private static boolean isPrime(int number) {
        if (number % 2 == 0) {
            return number == 2;
        }

        for (int i = 3; number >= i * i; i += 2) {
            if (number % i == 0) {
                return false;
            }
        }

        return true;
    }
}

输出

> java p3
6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176

您的原始代码输出 0 代替上面的最终(37 位)数字。所以最直接的问题是long 无法容纳足够的信息。但超出这一点,您根本无法使用上述算法进行足够快的计算。

如果我们对上面的代码做一些简单的事情,比如替换这一行:

 if (isPrime(mersenne)) {

与:

if (mersenne.isProbablePrime(10)) {

代码会在缓慢爬行之前吐出前 20 个完美数字。调整isProbablePrime()确定性 参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2019-09-29
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多