c - Newton Raphson 迭代陷入无限循环

标签 c floating-point-precision newtons-method

我是这个主题的新手,找不到原因:程序有时有效,有时无效(问完问题后,它根本不想接受我的答案,而我可以我想写多少就写多少,它没有反应,只是列出数字,我给了小费)

  #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*szamtipp 也是如此。因此,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/

相关文章:

java - Java 中求复数根的牛顿法

c - 使用灵活数组成员时正确的 malloc 大小

c - scanf() 将换行符保留在缓冲区中

c++ - 如何测试这个C库?

python - 如何从变量指定浮点小数精度?

julia - 在 Julia 中实现多元牛顿法

c - C 简介 : Addition and Looping

excel - Excel 如何正确评估 FACT(170)/FACT(169)?

python - 在不同平台上使用 Numpy

python - 在 pandas/python 中加速 newton-raphson