我发现了一个有趣的问题,我想我可以尝试做;几乎立即我发现了一个问题,我似乎无法解决。
当我运行代码时,没有错误,但它只是运行而不返回任何内容。我的循环似乎没问题,我知道我找素数的算法有效,所以我不知道出了什么问题。
经过大量编辑,我仍然有同样的问题,但是当在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 类,它允许您控制所需的精度级别。
有关更多信息,您可能需要阅读有关双精度的维基百科页面和/或本文
此外,似乎b
和j
总是一起增加,这是这里的另一个问题。暴力解决方案将有 2 个嵌套循环,每个循环增加一个变量,而不是 1 个循环增加两个变量。
关于优化的评论:您可能希望使用埃拉托色尼筛来提高查找素数的效率。
-
让 j 从 2 运行到 b(或 b/something,以获得更好的性能)。
-
由于您的PI并不完美,因此我认为您期望一些宽容度。2个素数的除法通常会产生实数,这很少等于您的PI。您可以与 PI +/- 比较一些公差,以便为解决方案提供更好的机会。
我在你的代码中看到一些问题:
-
b
和j
同时被激化,所以这里if (b / j == pi)
,b/j
总是 1 - 你的循环应该从 2 开始,因为 0,1 不是质数:
for (int b = 2, j = 2; notequal == true
;....)` -
if ((isPrime(b)) && (isPrime(j)))
检查相同的号码primeness
- 我检查了在我的机器上运行。由于
b
和j
,它永远运行
。
您不必比较每个可能的数字,也不需要比较任何数字。 你想找到一个素数,当乘以 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,所以你永远不会打印出任何东西。