3

我发现了一个有趣的问题,我想我可以尝试做;我几乎立即发现了一个我似乎无法解决的问题。

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

经过大量编辑后,我仍然遇到同样的问题,但是当在 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;
            }
        }
    }
}
4

5 回答 5

0

变量 numerator 和 current 都是 int,因此将它们相除会得到一个 int,其中最接近 pi 的是 3,相差超过 0.1,这意味着 isClose 永远不会返回 true,所以你永远不会打印任何东西出去。

于 2014-11-11T01:14:05.390 回答
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

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

于 2012-08-14T07:54:06.670 回答
0

在谈论双打时,您不能期望完美的准确性,双打不是实数(或有理数)。

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

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

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

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


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

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

于 2012-08-14T06:41:45.247 回答
0

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

  1. b并且j同时增加,所以在这里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相同。
于 2012-08-14T06:52:42.513 回答
0
  1. 让 j 从 2 运行到 b(或 b/something,以获得更好的性能)。

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

于 2012-08-14T07:02:13.160 回答