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)
。