Java: 通过递归计算 Pi (if else only)
Java: calculate Pi via recursion (if else only)
我必须用这个 Formula 来计算数字 Pi。
注:初学者 java。
到目前为止我的想法:
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(20) * 6.0));
}
static double quadraticFractionSum(double counter) {
if (counter == 1000.0) {
return counter;
} else {
return counter + 1 / (quadraticFractionSum(counter + 1) * quadraticFractionSum(counter + 1));
}
}
问题是需要永远计算:/
- 已解决:答案:Alain O'Dea + Balwinder Singh
新问题:
代码不计算圆周率 - 已解决答案:Aimert
非常感谢您的帮助
你有三个问题(一个可能是轻微的,非致命的):
- 严重影响性能:不必要的递归二次复杂度
- 严重的正确性:你从错误的计数开始并且递归的情况是错误的
- 次要但有启发性:不必要地使用浮点数和可能的舍入错误
不必要的递归二次复杂度
您以二次方式重新计算递归,这非常昂贵。当您只需要执行 980 次时,您正在执行 2^980 次递归调用(请注意,我在这里谈论的是单个方法调用而不是堆栈深度)。这是一个糟糕的成本爆炸。
从错误的计数开始,递归的情况是错误的
其次,您需要从 1 开始 count,而不是 20,并且您需要在递归情况下执行 1/counter^2 + quadSum(count+1) 。我在那里使用 1.0d/counter^2 以确保 Java 使用 double 算法。否则它将使用积分运算并仅给出 1 或 0 作为结果。
最后一次迭代的基本情况(在 1000 次迭代时停止近似)应该 return 1.0d/counter^2。相反,我选择制作基本案例 iterations + 1 和 return 0.0d 因为我认为它更干净。
不必要地使用浮点数和可能的舍入错误
最后,由于累积的浮点错误,您的基本情况可能无法正常工作。
== 是 double 或任何浮点数的冒险命题。每次计算都会累积精度误差,很容易导致它不等于您的基本情况的整数。
counter 应该是 int。试试看它是否加速。
建议的解决方案
下面是演示我为您提出的修复建议的代码:
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(1) * 6.0));
}
static double quadraticFractionSum(int counter) {
if (counter == 1001) {
return 0.0d;
} else {
return 1.0d / (counter * counter) + quadraticFractionSum(counter + 1);
}
}
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(1) * 6));
}
static double quadraticFractionSum(int counter) {
if (counter == 1000) {
return 1d / (counter * counter);
} else {
double quadraticFractionSum = quadraticFractionSum(counter + 1);
return quadraticFractionSum + 1d / (counter * counter);
}
}
当你执行 1 / 任何操作时,它会给你一个整数结果,因为这两个数字都是整数。你必须指定你想要一个双结果,否则你会得到零(因此是“1d”)。
我必须用这个 Formula 来计算数字 Pi。 注:初学者 java。 到目前为止我的想法:
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(20) * 6.0));
}
static double quadraticFractionSum(double counter) {
if (counter == 1000.0) {
return counter;
} else {
return counter + 1 / (quadraticFractionSum(counter + 1) * quadraticFractionSum(counter + 1));
}
}
问题是需要永远计算:/ - 已解决:答案:Alain O'Dea + Balwinder Singh
新问题: 代码不计算圆周率 - 已解决答案:Aimert
非常感谢您的帮助
你有三个问题(一个可能是轻微的,非致命的):
- 严重影响性能:不必要的递归二次复杂度
- 严重的正确性:你从错误的计数开始并且递归的情况是错误的
- 次要但有启发性:不必要地使用浮点数和可能的舍入错误
不必要的递归二次复杂度
您以二次方式重新计算递归,这非常昂贵。当您只需要执行 980 次时,您正在执行 2^980 次递归调用(请注意,我在这里谈论的是单个方法调用而不是堆栈深度)。这是一个糟糕的成本爆炸。
从错误的计数开始,递归的情况是错误的
其次,您需要从 1 开始 count,而不是 20,并且您需要在递归情况下执行 1/counter^2 + quadSum(count+1) 。我在那里使用 1.0d/counter^2 以确保 Java 使用 double 算法。否则它将使用积分运算并仅给出 1 或 0 作为结果。
最后一次迭代的基本情况(在 1000 次迭代时停止近似)应该 return 1.0d/counter^2。相反,我选择制作基本案例 iterations + 1 和 return 0.0d 因为我认为它更干净。
不必要地使用浮点数和可能的舍入错误
最后,由于累积的浮点错误,您的基本情况可能无法正常工作。
== 是 double 或任何浮点数的冒险命题。每次计算都会累积精度误差,很容易导致它不等于您的基本情况的整数。
counter 应该是 int。试试看它是否加速。
建议的解决方案
下面是演示我为您提出的修复建议的代码:
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(1) * 6.0));
}
static double quadraticFractionSum(int counter) {
if (counter == 1001) {
return 0.0d;
} else {
return 1.0d / (counter * counter) + quadraticFractionSum(counter + 1);
}
}
public static void main(String[] args) {
System.out.println(Math.sqrt(quadraticFractionSum(1) * 6));
}
static double quadraticFractionSum(int counter) {
if (counter == 1000) {
return 1d / (counter * counter);
} else {
double quadraticFractionSum = quadraticFractionSum(counter + 1);
return quadraticFractionSum + 1d / (counter * counter);
}
}
当你执行 1 / 任何操作时,它会给你一个整数结果,因为这两个数字都是整数。你必须指定你想要一个双结果,否则你会得到零(因此是“1d”)。