簡體   English   中英

為什么這些奇怪的數字導致此代碼失敗?

[英]Why does this code fail for these weird numbers?

我編寫了一個函數,該函數使用Newton-Raphson方法查找數字a的立方根,以找到函數f(x)= x ^ 3-a的根。

#include <stdio.h>
#include <math.h>

double cube_root(double a)
{
    double x = a;
    double y;
    int equality = 0;

    if(x == 0)
    {
        return(x);
    }

    else
    {
        while(equality == 0)
        {
            y = (2 * x * x * x + a) / (3 * x * x);

            if(y == x)
            {
                equality = 1;
            }

            x = y;

        }

    return(x);

    }
}

對於a = 20(藍色)和a = -20(紅色)的f(x)http://graphsketch.com/?eqn1_color=1&eqn1_eqn=x*x*x%20-%2020&eqn2_color=2&eqn2_eqn=x*x*x %20%2B%2020&eqn3_color = 3&eqn3_eqn =&eqn4_color = 4&eqn4_eqn =&eqn5_color = 5&eqn5_eqn =&eqn6_color = 6&eqn6_eqn =&x_min = -8 X_MAX = 8&Y_MIN = -75 Y_MAX = 75&x_tick = 1&y_tick = 1&x_label_freq = 5&y_label_freq = 5&do_grid = 0&bold_labeled_lines = 0&line_width = 4&image_w = 850&image_h = 525

該代碼似乎運行良好,例如,它可以很好地計算出338947578237847893823789474.324623784的立方根,但是對於某些數字(例如4783748237482394)卻怪異地失敗了? 該代碼似乎陷入了無限循環,必須手動終止。

誰能解釋為什么代碼在此號碼上失敗? 我已經包含了該圖,以表明,使用a的起始值,該方法應始終提供越來越近的估計,直到兩個值等於工作精度為止。 所以我真的不知道這個數字有什么特別之處。

除了發布不正確的公式...

您正在執行浮點運算,並且浮點運算具有舍入錯誤。 即使存在舍入誤差,您也將非常非常接近多維數據集的根,但是您將無法獲得精確的位置(通常,多維數據集的根是非理性的,浮點數是有理數的)。

一旦您的x非常接近多維數據集的根,當您計算y時,您應該得到與x相同的結果,但是由於舍入誤差,您可能會得到與x非常接近但略有不同的結果。 所以x!= y 然后,您從y開始進行相同的計算,結果可能為x。 因此,您的結果將永遠在兩個值之間切換。

您可以使用三個數字x,y和z進行相同的操作,然后在z == y或z == x時退出。 這很可能會停止,並且通過一些數學運算,您甚至可以證明它會永遠停止。

最好計算x的變化,並確定該變化是否足夠小,以使下一步將不會舍入x(舍入誤差除外)。

不應該是:

y = x-(2 * x * x * x + a)/(3 * x * x);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM