找到最小的素数,当除以等于 pi 到 4 位小数时?爪哇岛

  • 本文关键字:小数 pi 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;
            }
        }
    }
}

当谈论双精度时,你不能指望完美的准确性,双精度不是实数(或有理数)。

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

因此,比较两个双精度的恒等式 (==) 很少返回所需的结果

就您的目的而言,一个有效的替代方案可能是使用 java 的 BigDecimal 类,它允许您控制所需的精度级别。

有关更多信息,您可能需要阅读有关双精度的维基百科页面和/或本文


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

关于优化的评论:您可能希望使用埃拉托色尼筛来提高查找素数的效率。

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

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

我在你的代码中看到一些问题:

  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. 我检查了在我的机器上运行。由于bj,它永远运行

您不必比较每个可能的数字,也不需要比较任何数字。 你想找到一个素数,当乘以 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

这可能不完全是你想要的,但你可以看到这更简单,更快捷。

变量分子和电流都是整数,所以将它们除以会给你一个整数,其中最接近 pi 的是 3,它有超过 0.1 的差异,这意味着 isClose 永远不会返回 true,所以你永远不会打印出任何东西。

最新更新