C中pi的无限级数逼近不终止
Infinite series approximation of pi in C not terminating
这是我的代码,当使用 print 语句时它似乎是一个无限循环:
我可以解决的一些潜在问题是整数除法,也许可以确定算法是否终止,如果它总是有正确的输出,也许是 C 语言的一些我不理解的特性导致了这个问题?
根据我的理解,总和趋于负无穷大,一旦达到 epsilon 精度的近似值,就会触发 break 语句并结束算法。
#include <stdio.h>
int main()
{
double pi, sum, epsilon;
long long i=1;
long long max = 2147483647;
printf("Pleas enter the desired accuracy epsilon : ");
scanf("%f", &epsilon);
while (i<max){
if (i%2 == 0){
sum = -4.0/(2.0*i-1);
}else if (i%2 ==1){
sum = (4.0/(2.0*i-1));
}
if (sum < epsilon){
break;
}
pi += sum;
}
printf("The value of pi approximated to epsion : %f is %f\n", epsilon, pi);
return 0;
}
您没有在 while
循环中递增 i
的值。结果,它的值始终保持为 1。
在 while
循环结束 }
之前处理完成后增加 i
。
初始化 pi, sum, epsilon
的值,以便您在第一次尝试读取它们的值时不会 运行 进入未定义的行为。
此外,启用适当的选项(-Wall
与 GCC)编译器会警告您,您正试图将 float
读入 double
。
warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double *' [-Wformat=]
scanf("%f", &epsilon);
~^ ~~~~~~~~
因此您必须在 scanf
语句中使用正确的转换说明符:%lf
而不是 %f
。
如果你对数字2147483647
不是很讲究,只想要一个大的值,也可以用ULLONG_MAX
(来自limits.h
)来初始化max
而不是对值进行硬编码。
您需要在 while
循环中递增 i
值。
你的循环条件while(i < max)
总是满足的(无限循环)。因此 i
或 max
的值应该在循环内更改以永远结束循环。
您的代码有未定义的行为:
scanf("%f", &epsilon);
scanf
%f
需要一个 float *
,而不是 double *
。 double *
的正确格式是 %lf
.
您的循环条件 while (i<max)
等同于 while (1)
,因为 i
和 max
都不会在循环内更改它们的值。
这也意味着 sum
总是 4
:
sum = (4.0/(2.0*i-1));
// 4 / (2 * 1 - 1) = 4 / (2 - 1) = 4 / 1 = 4
pi += sum;
也有未定义的行为:pi
未初始化。
这是我的代码,当使用 print 语句时它似乎是一个无限循环:
我可以解决的一些潜在问题是整数除法,也许可以确定算法是否终止,如果它总是有正确的输出,也许是 C 语言的一些我不理解的特性导致了这个问题?
根据我的理解,总和趋于负无穷大,一旦达到 epsilon 精度的近似值,就会触发 break 语句并结束算法。
#include <stdio.h>
int main()
{
double pi, sum, epsilon;
long long i=1;
long long max = 2147483647;
printf("Pleas enter the desired accuracy epsilon : ");
scanf("%f", &epsilon);
while (i<max){
if (i%2 == 0){
sum = -4.0/(2.0*i-1);
}else if (i%2 ==1){
sum = (4.0/(2.0*i-1));
}
if (sum < epsilon){
break;
}
pi += sum;
}
printf("The value of pi approximated to epsion : %f is %f\n", epsilon, pi);
return 0;
}
您没有在 while
循环中递增 i
的值。结果,它的值始终保持为 1。
在 while
循环结束 }
之前处理完成后增加 i
。
初始化 pi, sum, epsilon
的值,以便您在第一次尝试读取它们的值时不会 运行 进入未定义的行为。
此外,启用适当的选项(-Wall
与 GCC)编译器会警告您,您正试图将 float
读入 double
。
warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double *' [-Wformat=]
scanf("%f", &epsilon);
~^ ~~~~~~~~
因此您必须在 scanf
语句中使用正确的转换说明符:%lf
而不是 %f
。
如果你对数字2147483647
不是很讲究,只想要一个大的值,也可以用ULLONG_MAX
(来自limits.h
)来初始化max
而不是对值进行硬编码。
您需要在 while
循环中递增 i
值。
你的循环条件while(i < max)
总是满足的(无限循环)。因此 i
或 max
的值应该在循环内更改以永远结束循环。
您的代码有未定义的行为:
scanf("%f", &epsilon);
scanf
%f
需要一个 float *
,而不是 double *
。 double *
的正确格式是 %lf
.
您的循环条件 while (i<max)
等同于 while (1)
,因为 i
和 max
都不会在循环内更改它们的值。
这也意味着 sum
总是 4
:
sum = (4.0/(2.0*i-1));
// 4 / (2 * 1 - 1) = 4 / (2 - 1) = 4 / 1 = 4
pi += sum;
也有未定义的行为:pi
未初始化。