我是这个主题的新手,找不到原因:程序有时有效,有时无效(问完问题后,它根本不想接受我的答案,而我可以我想写多少就写多少,它没有反应,只是列出数字,我给了小费)
#include <stdio.h>
float abszolut (float szam)
{
float abszoluterteke;
if (szam >=0)
abszoluterteke = szam;
else
abszoluterteke = -szam;
return abszoluterteke;
}
float negyzetgyok (float szam)
{
float pontossag = 0.000001;
float tipp = 1;
if (szam <0)
{
printf ("Megszakítás elfogadva! \nKöszönjük, hogy programunkat választotta!\n");
return -1;
}
else
{while (abszolut (tipp*tipp-szam) >= pontossag)
tipp = (szam/tipp + tipp)/2;
return tipp;
}
}
int main (void)
{
float alap, eredmeny;
for (;;)
{
printf ("Melyik számnak szeretnéd meghatározni a négyzetgyökét ilyen módszerrel?\n");
scanf ("%f", &alap);
eredmeny = negyzetgyok (alap);
if (eredmeny == -1)
return 1;
else
printf ("A(z) %f négyzetgyöke megfelelő közelítéssel: %f\n", alap, eredmeny);
}
return 0;
}
最佳答案
更改 abszolut (tipp*tipp-szam) >= pontossag*szam
一旦 tipp*tipp
接近 szam
,while 循环就必须停止。但是IEEE floating point computations精度有限:float
大约 7 位数字,double
大约 15 位数字。
所以 float szam
的错误大约是 0.0000001*szam
。 tipp
也是如此。因此,tipp*tipp-szam
上的错误高于 0.0000001*szam
。如果 szam
很大,这个误差很难低于 0.000001
。 即使使用 double
精度,while (abszolut (tipp*tipp-szam) >= pontossag)
也可能会为非常大的数字触发无限循环.
另一方面,如果 szam
非常小,比如 1e-10
会发生什么? while 循环过早退出并且平方1e-10 的根计算为关于 1e-3
的东西,而不是 1e-5
... 相对误差约为 10000%... 并且使用 double
不会改变任何东西!
为避免这种情况,您可以更改为 abszolut (tipp*tipp-szam) >= pontossag*szam
。
请注意,两侧具有相同的维度。如果 szam
以平方英尺为单位,则 tipp
将以英尺为单位,而 pontossag
的精度是无量纲的。比较具有相同维度的事物是一种很好的做法。
如果您一直注意到无限循环,请切换到 double 或增加 pontossag
。
为避免无限循环,添加一个计数器 int i;
并在迭代次数为 100 时退出 while 循环。100 应该足够了,因为你的 Newton-Raphson iteration具有二次收敛性。
关于c - Newton Raphson 迭代陷入无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28781485/