C++ 无限循环计算立方根

C++ 无限循环计算立方根,c++,newtons-method,C++,Newtons Method,我试着用牛顿的方法做一个函数来计算立方根,但出于某种原因,这里似乎有一个无限循环 #include <iostream> #include <math.h> using namespace std; double CubicRoot(double x, double e); int main() { cout << CubicRoot(5,0.00001); } double CubicRoot(double x, double e) {

我试着用牛顿的方法做一个函数来计算立方根,但出于某种原因,这里似乎有一个无限循环

#include <iostream>
#include <math.h>

using namespace std;

double CubicRoot(double x, double e);

int main()
{
    cout << CubicRoot(5,0.00001);
}

double CubicRoot(double x, double e)
{
    double y = x;
    double Ynew;
    do 
    {
        Ynew = y-((y*y)-(x/y))/((2*y)+(x/(y*y)));
        cout << Ynew;

    } while (abs(Ynew-y)/y>=e);

    return Ynew;
}
#包括
#包括
使用名称空间std;
双肘(双x,双e);
int main()
{

不能在迭代时更新
y
变量。 另外,使用
abs
是非常危险的,因为它可能会在某些编译器上舍入为整数

编辑

来阐明我的意思:使用<代码> ABS > <代码> <代码>可能会导致不同编译的隐式类型转换问题(见下面的注释)。并且真正的C++风格会使用注释中建议的<代码> <代码>标题(谢谢该响应)。 对代码的最小更改将是:

double CubicRoot(double x, double e)
{
    double y = x;
    double Ynew = x;
    do 
    {
        y = Ynew;
        Ynew = y-((y*y)-(x/y))/((2*y)+(x/(y*y)));
        cout << Ynew;

    } while (fabs(Ynew-y)/y>=e);
    return Ynew;
}
双立体窗(双x,双e)
{
双y=x;
双Ynew=x;
做
{
y=Ynew;
Ynew=y-((y*y)-(x/y))/((2*y)+(x/(y*y));
cout=e);
返回Ynew;
}
您可以更改

    Ynew = y-((y*y)-(x/y))/((2*y)+(x/(y*y)));
相当于,但更容易辨认的表达

    Ynew = y*(y*y*y+2*x)/(2*y*y*y+x)

哪一种是f(y)=y^3-x的哈雷方法,具有三阶收敛性。

它有多接近?你得到了什么输出?它似乎在收敛,还是到处都是数字?你得到的是NaN输出吗?因为Ynew、y和e没有变化(你在循环中没有改变y和x,所以Ynew在每次迭代中都保持不变)所以,你不改变任何变量,如果在第一次迭代之后不离开循环,你就永远不会离开它(可能是某处而不是Y,你必须使用YNEY或你的公式是错误的)。这是C++。而不是使用<代码> Fabs<代码>,最好是正确的头(<代码> <代码>)。并使用
std::abs
,这对于大多数数字类型来说都是正确的重载。@Mike:+1-由于abs与
的不确定性,原始代码甚至不能用我的g++编译-更改为正确的头
当然可以解决问题。
abs
并不危险。在某些编译器上它不会舍入为整数呃。有些人遇到的问题是他们没有包含正确的标题,所以他们得到的是
abs(int)
的声明,而不是
abs(double)
。要得到
abs(double)
您需要
#include
@robson3.14:不,在
中定义的特定于C++的重载可能在C头中不可用,因为C不支持重载。您可能只会得到
int abs(int)
,并且只有当它间接地包括
@robson3.14时-对于
math.h
中的内容的规范,您必须查看
math.h
的要求,而不是
math.h
cmath
之间的关系。特别是,
中还有没有的附加函数重载t在
math.h
中,包括
abs(float)
abs(double)
,和
abs(long double)