在尝试设计算法时,我偶然发现了这个问题。这不是家庭作业。
设P_i =第一个i素数的数组。现在我需要最小的i
,以便
Sum<n=0..i> 1 / (P_i[n]*P_i[n]) >= 1.
(如果存在i
)。
i
&#39;素数的近似值为i*log(i)
。所以我在Java中试过这个:
public static viod main(String args[]) {
double sum = 0.0;
long i = 2;
while(sum<1.0) {
sum += 1.0 / (i*Math.log(i)*i*Math.log(i));
i++;
}
System.out.println(i+": "+sum);
}
然而,上述情况并未完成,因为它收敛到0.7。但是,在Java中1/100000000^2
轮到0.0
,这就是为什么它不起作用的原因。出于同样的原因,如果用
sum += 1.0 / (i*i)
如果我没有弄错,那么应该达到1
,因为总和应该比1/2^i
更快,而后者会收敛到1
。换句话说,这表明Java舍入导致总和不能达到1
。我认为我的问题的最小i
应该存在。
答案 0 :(得分:7)
在这个问题的数学方面,而不是java方面:
如果我理解了这个问题,就没有解决办法(没有i的价值)。
对于素数{p_1,p_2,... p_i}的任何有限集P_i,让N_i为直到p_i,{1,2,3,...,p_i}的所有整数的集合。和1 / p ^ 2(对于P_i中的所有p_n)将小于N_i中x的所有1 / x ^ 2的总和。
1 / x ^ 2 tends to ~1.65之和但由于1永远不会出现在素数集中,因此总和受限于~0.65
答案 1 :(得分:2)
你不能使用double,因为它不统一。你应该使用分数。我找到了这个班级https://github.com/kiprobinson/BigFraction
然后我试着找到发生的事情:
public static void main(String args[]) {
BigFraction fraction = BigFraction.valueOf(1, 4);
int n = 10000000, status = 1, num = 3;
double limit = 0.4;
for (int count = 2; count <= n;) {
for (int j = 2; j <= Math.sqrt(num); j++) {
if (num % j == 0) {
status = 0;
break;
}
}
if (status != 0) {
fraction = fraction.add(BigFraction.valueOf(1,BigInteger.valueOf(num).multiply(BigInteger.valueOf(num))));
if (fraction.doubleValue() >= limit){
System.out.println("reached " + limit + " with " + count + " firsts prime numbers");
limit += 0.01;
}
count++;
}
status = 1;
num++;
}
}
这是输出:
reached 0.4 with 3 firsts prime numbers
reached 0.41000000000000003 with 4 firsts prime numbers
reached 0.42000000000000004 with 5 firsts prime numbers
reached 0.43000000000000005 with 6 firsts prime numbers
reached 0.44000000000000006 with 8 firsts prime numbers
reached 0.45000000000000007 with 22 firsts prime numbers
而且不过一分钟。我调试它,发现它变得非常慢和慢,我不认为,即使在无穷大它也可以达到1 :)(但不知道如何证明它)。
答案 2 :(得分:0)
我猜你使用默认Math.log
乘以float i
时可能会失去所需的精度。我认为这可以通过使用适当的RoundingMode来处理。请参阅setRoundingMode