我在这个话题上是个初学者,不知道原因:有时程序工作,有时不工作(问完问题,它根本不想接受我的答案,我想写多少就写多少,它不回答,只列出数字,我就喝了一杯)

  #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的精度有限:约7位表示float,15位表示double
所以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的精度是无量纲的。比较具有相同维度的事物是一个很好的做法。
如果您一直注意到无限循环,请切换到双精度或增加pontossag
为了避免无限循环,如果计数器的迭代次数为100,则添加计数器int i;并退出while循环。100应该足够了,因为Newton-Raphson iteration具有二次收敛性。

关于c - 牛顿拉夫森迭代陷入无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28781485/

10-11 17:53