【问题标题】:Infinite loop calculating cubic root计算三次根的无限循环
【发布时间】:2013-09-06 15:05:41
【问题描述】:

我正在尝试制作一个通过牛顿法计算三次根的函数,但由于某种原因我似乎在这里出现了无限循环?

#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;
}

【问题讨论】:

  • 距离有多近?
  • 你得到什么输出?它似乎正在收敛,还是到处都是数字?你得到 NaN 输出了吗?
  • 因为 Ynew,y 和 e 不会改变(你不会在循环中改变 y 和 x,所以 Ynew 在每次迭代时仍然保持不变)。所以你不要改变任何变量,如果你在第一次迭代后不离开循环,你将永远不会离开它(也​​许在某个地方你必须使用 Ynew 或者你的公式不正确)。

标签: c++ newtons-method


【解决方案1】:

迭代时您尚未更新您的y 变量。 同样使用abs 也很危险,因为它可能会在某些编译器上舍入为整数。

编辑

澄清我的意思:使用abs&lt;math.h&gt; 可能会导致不同编译的隐式类型转换问题(请参阅下面的评论)。真正的 c++ 风格将使用 cmets 中建议的 &lt;cmath&gt; 标头(感谢您的回复)。

对您的代码的最小更改是:

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;
}

【讨论】:

  • 这是 C++。与其使用fabs,不如包含正确的标头(&lt;cmath&gt;)并使用std::abs,它对于大多数数字类型都正确重载。
  • @Mike: +1 - 由于 abs 与 &lt;math.h&gt; 的歧义,原始代码甚至无法用我的 g++ 编译 - 更改为正确的标头 &lt;cmath&gt; 当然可以解决问题。
  • abs危险的。它在某些编译器上 not 舍入为整数。有些人遇到的问题是他们没有包含正确的标题,所以他们得到了abs(int) 的声明,而不是abs(double)。要获得abs(double),您需要#include &lt;cmath&gt;
  • @robson3.14:不,&lt;cmath&gt; 中定义的 C++ 特定重载可能在 C 标头中不可用,因为 C 不支持重载。你可能只会得到int abs(int),而且只有当它间接包含&lt;stdlib.h&gt;
  • @robson3.14 - 对于math.h 中的内容的规范,您必须查看math.h 的要求,而不是math.hcmath 之间的关系。特别是,&lt;cmath&gt; 中有 附加 函数重载,而 math.h 中没有,包括 abs(float)abs(double)abs(long double)
【解决方案2】:

你可以改变

    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 的哈雷方法,具有三阶收敛性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 2011-07-12
    • 2018-09-22
    • 2015-01-06
    • 2015-10-02
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    相关资源
    最近更新 更多