为什么我的while循环无限?
问题描述:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc != 2) {
printf("Too many arguments.\n", argc);
return 1;
}
double n;
n = atof(argv[1]);
if (n<0) {
printf("Negative argument.\n");
return 1;
}
double r;
r = n;
int iteration;
iteration = 0;
while(calcError(n,r)<1e-6) {
iteration = iteration +1;
r = (r + n/r)/2;
printf(" %d. sqrt(%f)~= %f,error=%e\n",iteration,n,r,calcError(r,n));
}
printf("sqrt(%f)=%f to six places\n",n,r);
return 0;
}
int calcError (double n, double r) {
double delta;
delta = n-r*r;
delta = delta > 0 ? delta : -delta;
return 0;
}
运行此代码会生成一个无限循环。我还得到一个警告:格式'%e'需要类型'double'的参数,但参数5的类型为'int'[-Wformat]。为什么是这样?为什么我的while循环无限?
答
calcError
总是返回0
,所以
while(calcError(n,r)<1e-6)
一样好,因为
while(0 < 1e-6)
或
while(true)
至于警告,编译器说,究竟出了什么问题:calcError
回报一个int
,但您提供的格式字符串(%e
)需要double
。这将产生未定义的行为。如下更改返回类型将解决此问题。
看着你的代码,我想你想循环,只要错误大于1e-6
。如果这是正确的,你可能需要修改你的calcError
是如下:
int calcError (double n, double r)
{
double delta;
delta = n-r*r;
delta = delta > 0 ? delta : -delta;
return delta;
}
可缩短至
double calcError(double n, double r)
{
return fabs(n-r*r);
}
,改变你的循环条件循环,直到它的体积更小:
while(calcError(n,r) > 1e-6)
答
在你calcError()
功能,你有,
return 0;
因此在您的表达中,calcError()
将始终为零。
和(0 < 1e-6)
总是如此。
答
你有while(calcError(n,r)<1e-6)
和calcError
总是返回0,所以当然你的循环将永远持续下去。我想你的意思是让calcError
返回delta
而不是0
。
谢谢,这是有道理的。但是,使用该更改运行代码仍会生成相同的警告。不再有无限的while循环,它现在完全绕过while循环,并显示:sqrt(24.000000)= 24.000000到六个地方 – normystar
我认为只要误差大于你的epsilon就想循环,所以使用这个:'while(calcError(n,r)> 1e-6)' – krzaq
我很确定[this](http://melpon.org/wandbox/permlink/Oqw54hodZugBWEnn)正是你想要的。顺便说一句,请注意,对'printf'调用'calcError'具有相反的顺序。 – krzaq