我编写了一个函数来查找数字a的立方根,使用Newton-Raphson方法找到函数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的起始值,此方法应始终保持更近和更近的估计,直到两个值等于工作精度。因此,我对这个数字并不感到特别。
答案 0 :(得分:2)
除了发布错误的公式......
您正在执行浮点运算,浮点运算具有舍入误差。即使有舍入错误,你也会非常接近一个立方根,但你不会准确到达那里(通常立方根是不合理的,浮点数是合理的)。
一旦你的x非常接近立方根,当你计算y时,你应该得到与x相同的结果,但是由于舍入错误,你可能得到非常接近x的东西,但是稍微不同。所以x!= y。然后你用y开始进行相同的计算,你可能得到x作为结果。因此,您的结果将永远在两个值之间切换。
你可以用三个数字x,y和z做同样的事情,当z == y或z == x时退出。这更有可能停止,通过一些数学,你甚至可以证明它将永远停止。
最好计算x的变化,并确定该变化是否足够小,以便下一步不会改变x,除了舍入误差。
答案 1 :(得分:1)
不应该是:
y = x - (2 * x * x * x + a)/(3 * x * x);