[英]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);
}
}
該代碼似乎運行良好,例如,它可以很好地計算出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.