【问题标题】:Recursive function returns a nan (c++)递归函数返回一个 nan (c++)
【发布时间】:2014-01-22 16:53:11
【问题描述】:

当我使用 while 循环时,函数返回一个正确的值,但是当我使函数递归时,它返回一个 nan。出于调试目的,我在返回它之前计算了 value(x) 并给出了正确的答案,但是在将值返回给调用函数之后,它是一个 nan。另一件事是,程序不会为 x 的系数取 0。任何尝试都会导致 nan。下面是我的代码(所有这些只是为了确保我没有提供足够的信息):

// This is my first useful program
// to calculate the root (Solution) of exponential
// functions up to the fourth degree using
// Newton-Raphson method and applying a recursive function
#include <iostream>
#include <cstdlib>
#include <string>


using namespace std;

// Below is the function fGetRoot's prototype declaration
// c4, c3, etc are the coefficients of x in the 4th power, 3rd power
// etc, while c is the constant

float fGetRoot (float c4, float c3, float c2, float c1, float c);
float fPowerFunc(float fPowered, int iPower);
float x;    // declaring this as global variables so they can be initialized in the calling function
int i=10;  //  and be used in the recursive function without being reinitialized during each recursion


int main()
{
    float c4, c3, c2, c1, c;
    float fRoot;

    cout << "Hello, I am a genie for calculating the root of your problems\
up to the fourth power" << endl;
    cout << "Please enter the values of the coefficients of x to the power 4\
, 3, 2, 1 and the constant respectively" << endl;

    cout << "x^4:" << endl;
    cin >> c4;
    cout << "\n x^3:" << endl;
    cin >> c3;
      cout << "x^2:" << endl;
    cin >> c2;
    cout << "\n x:" << endl;
    cin >> c1;
      cout << "Constant, C:" << endl;
    cin >> c;
    cout << "\nEnter the initial iteration. Any figure is fine. The closer to the answer, the better" << endl;
    cin >> x;

    i=10; // gets the number of times to iterate. the larger, the more accurate the answer
    fRoot = fGetRoot(c4, c3, c3, c1, c);
    cout <<"\nAnd the root is: " << fRoot << "\n";

    return 0;
}


// The fGetRoot function

float fGetRoot(float c4, float c3, float c2, float c1, float c)
{
    float fTemp1, fTemp2, fTemp3, fTemp4;

    // the series of lines below are equivalent to the one line below but clearer
    fTemp1 = c4*fPowerFunc(x,4);
    cout << "This is the value of c4*x^4: "<< fTemp1 << endl; // for debugging purposes
    fTemp2 = c3*fPowerFunc(x,3);
    fTemp3 = fTemp2 + fTemp1;
    fTemp1 = c2*fPowerFunc(x,2);
    cout << "This is the value of c2*x^2: "<< fTemp1 << endl; //for debugging purposes
    fTemp2 = c1*fPowerFunc(x,1);
    fTemp4 = fTemp1 + fTemp2 + c;
    fTemp1 = fTemp3 + fTemp4;
    fTemp2 = 4*c4*fPowerFunc(x,3);
    fTemp3 = 3*c3*fPowerFunc(x,2);
    fTemp4 = fTemp2 + fTemp3 + 2*c2*x;
    fTemp2 = fTemp4;
    fTemp3 = fTemp1/fTemp2;
    fTemp1 = fTemp3;
    fTemp2 = x - fTemp1;
    x = fTemp2;
    i--;

    // The line below is equivalent to the "fTemp" series of lines... just to be sure

//x=x-(c4*fPowerFunc(x,4)+c3*fPowerFunc(x,3)+c2*fPowerFunc(x,2)+c1*fPowerFunc(x,1)+c)/(4*c4*fPowerFunc(x,3)+3*c3*fPowerFunc(x,2)+2*c2*x);

    cout << "\nThis is x: " << x << endl;
    i--;
    if(i==0)
        return x;
    x=fGetRoot(c4, c3, c2, c1, c); // Let the recursion begin...

}

// A simpler approach to the fPowerFunc(). This gets two numbers and powers the left one by the right one. It works right
float fPowerFunc(float fPowered, int iPower)
{
    float fConstant=fPowered;
    while(iPower>0)
    {
        fPowered *=fConstant;
        iPower--;
    }
    return fPowered;
}

【问题讨论】:

  • 只是好奇:为什么你需要做两次i--?在cout 之前和cout 之后?
  • 谢谢。直到现在我才注意到这个错误!

标签: c++ recursion return


【解决方案1】:

您只是在函数末尾忘记了return x。编译器可能会在寄存器中保存临时变量,以保存返回值并使其看起来可以工作。

您应该在编译时启用更多警告,以便编译器可以告诉您类似的事情。

【讨论】:

  • 他正在使用全局 float 。在这种情况下return 是必要的吗?
  • @VusP 他正在使用main()中的返回值,所以是的
  • 对不起,我不明白我忘记在哪里返回 x 。 i 变量应该计算递归次数。当我==0;是它应该返回 x 的值的时候。但即便如此,我还是收到“控制到达非无效函数的结尾”警告。谢谢。
  • @Amani 当i==0 innermost gGetRoot() 返回时,控制返回到 i 为 1 且您已递归的级别。现在执行在调用后继续,需要再次返回。如果您使用调试器单步执行它,您应该会看到i==0 的那一刻并查看调用堆栈。每个级别都需要返回。
  • 或者简单地说:return fGetRoot(c4, c3, c2, c1, c); 它比使用全局更整洁。如果你真的想使用全局值,为什么return x;i==0
【解决方案2】:

另外一个问题是这个语句:if(i==0),应该换成if(i&lt;=0)

在浮点领域严格来说没有相等的概念。范围内的数字是更正确的抽象。例如,要测试 f 是否近似为零,您可以这样做: if(f &gt;= -epsilon &amp;&amp; f &lt;= epsilon) ... 其中epsilon 是标准FLT_EPSILON 或其他一些特定于应用程序的精度常数。

【讨论】:

  • In float realm there is no concept of equality strictly speaking. 严格来说当然有。在现实世界中存在计算机的情况下,它只是不会按照您的想法进行
猜你喜欢
  • 2016-03-01
  • 2011-01-22
  • 2017-05-14
  • 1970-01-01
  • 2013-08-07
  • 2022-01-02
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
相关资源
最近更新 更多