问题描述
我有这个任务
Pi 的值可由以下乘积确定
2 * 2 4 * 4 6 * 6 N * N
Pi = 2 * ----- * ----- * ----- * ... * -----------------
1 * 3 3 * 5 5 * 7 (N - 1) * (N + 1)
编写一个C程序,计算Pi的近似值,只要一般项大于1 + 10-9。
#include <stdio.h>
#include <stdlib.h>
int main() {
double pi;
const double End =
1.0 + (1.0 / (10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0));
double N = 2.0;
pi = 2.0 * ((N * N) / ((N - 1.0) * (N + 1.0)));
while (pi > End) {
N += 2.0;
pi *= ((N * N) / ((N - 1.0) * (N + 1.0)));
}
printf("%lf",pi);
return 0;
}
我真的无法理解事情是如何运作的。我设法只使用了 double
变量并将 .0
添加到所有数字文字中,但是程序卡住了并且在我启动它时没有给出任何值。
为什么?
解决方法
一个简单的解决方案是跟踪旧值,从而将循环替换为以下(需要
double pi_old = pi + 1e9; // initialize to large value
while (fabs(pi-pi_old) > End){
pi_old = pi; // store this
// then compute next
N += 2.0;
pi *= ((N * N) / ((N - 1.0) * (N + 1.0)));
}
另外,正如我所评论的,
const double End =
1.0 + (1.0 / (10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0 * 10.0));
相当于
const double End = 1.0 + ( 1.0e-9 ); // 1.0e-9 = 1.0*10^(-9)
,
此条件 while (pi > End)
不符合要求。
它会在总乘积大于大约 1 时循环,这对于 Pi 的任何近似值都将是无限循环。
说明仅指最后一部分 (N*N)/( (N-1) * (N+1) )
大于 1 + 一点点。
所以解决方案是单独计算最后一部分并仅在循环条件中使用它。
(我故意不提供更多细节或代码,因为
How do I ask and answer homework questions? )