找到最小的素数,当它被分成等于Pi到4个小数位数时? Java的

时间:2012-08-14 06:35:13

标签: java numbers pi

我发现了一个有趣的问题,我认为我可以尝试做;几乎立即我发现了一个问题,我似乎无法修复。

当我运行我的代码时,没有错误,但它只是在没有返回任何内容的情况下运行。我的循环似乎没问题,我知道我找到素数的算法是有效的,所以我不知道出了什么问题。

编辑了很多之后,我仍然遇到同样的问题,但是当在python中运行几乎相同的代码时,python代码会运行并实际返回结果。这是更改后的代码:

public class PrimeNumtoPi {

    static double pi = Math.PI;
    static double accuracy = 0.1;
    static int range = 10000;

    //checks whether an int is prime or not.
    static boolean isPrime(int n) {
        if(n % 2 == 0) {
            return false;
        } else {
            int i = 3;
            while (i < n / 2) {
                if(n % i == 0) {
                    return false;
                }
                i += 2;
            }
        }
        return true;
    }

    public static int nearestwhole(double n) {
        double remainder = n%1;
        if(remainder >= 0.5) {
            return (int) (n - remainder + 1);
        } else {
            return (int)(n - remainder);
        }
    }

    public static boolean isClose(double n) {
        if(abs(n - pi) < accuracy) {
            return true;
        } else {
            return false;
        }
    }

    public static double abs(double n) {
        if(n < 0) {
            return n * -1;
        } else {
            return n;
        }
    }

    public static void main(String[] args) {
        int current = 3;
        while(current <= range) {
            int numerator = nearestwhole(current * pi);
            if (isPrime(numerator)) {
                if(isClose(numerator/current) == true) {
                    System.out.println(numerator + " and " + current);
                }
            }
            current += 2;
            while(isPrime(current) == false) {
                current += 2;
            }
        }
    }
}

5 个答案:

答案 0 :(得分:0)

在谈论双打时,你不能指望完美的准确性,双打真实(或理性)数字。

请记住,在任何(非平凡的)范围内存在无数个有理数,但只有有限数量的位来表示它们。

因此,比较两个双打的身份(==)很少会返回想要的结果

为了您的目的,有效的替代方法可能是使用java的BigDecimal类,它可以控制所需的精度级别。

有关详细信息,您可能需要阅读wikipedia page双精度和/或this article


此外,bj似乎总是在一起增加,这是另一个问题。一个强力解决方案将有2个嵌套循环,每个循环增加一个变量,而不是增加两个循环。

关于优化的评论:您可能希望使用sieve of eratosthenes来提高查找素数的效率。

答案 1 :(得分:0)

我发现您的代码中存在一些问题:

  1. bj会同时增加,因此if (b / j == pi)b/j始终为1
  2. 你的循环应该从2开始,因为0,1不是素数:for (int b = 2, j = 2; notequal == true; ....)`
  3. if ((isPrime(b)) && (isPrime(j)))检查primeness
  4. 的相同号码
  5. 我检查了我的机器上的运行情况。由于bj相同,它会永远运行。

答案 2 :(得分:0)

  1. 设j从2运行到b(或b / something,以获得更好的性能)。

  2. 由于你的PI并不完美,所以我认为你期望有一些宽容。 2个素数的划分通常会产生实数,这很少等于您的PI。您可以与PI +/-一些容差进行比较,以便为解决方案提供更好的机会。

答案 3 :(得分:0)

您不必比较所有可能的数字,也不需要比较任何数字。你想找到一个素数,乘以PI也是一个素数。

public static void findSmallInt() {
    double pi = 3.1415;
    for (int i = 3; ; i += 2) {
        if (!isPrime(i)) continue;
        int num = (int) Math.round(i * pi);
        if (!isPrime(num)) continue;
        if (round4((double) num / i) == pi) {
            System.out.println(num + "/" + i + "= "+(double) num/i);
            break;
        }
    }
}

private static double round4(double v) {
    return Math.round(v * 1e4) / 1e4;
}

public static void main(String... args) {
    findSmallInt();
}

打印

977/311= 3.1414790996784565

这可能不是您想要的,但您可以看到这更简单,更快。

答案 4 :(得分:0)

变量分子和当前都是整数,所以除以它们会给你一个int,你可以得到的最接近的是3,它有超过0.1的差异,这意味着isClose永远不会返回true,所以你会永远不要打印任何东西。