2014-01-05 8 views
0

, когда я использую цикл while, функция возвращает правильное значение, но когда я делаю функцию рекурсивной, она возвращает nan. Для целей отладки я отключил значение (x) перед его возвратом и дал правильный ответ, но после возвращения значения вызывающей функции это нан. Еще одна вещь, программа не принимает 0 для коэффициентов x. Любые попытки приводят к нан. Ниже мой код (все это только, чтобы убедиться, что я не давал достаточной информации):Рекурсивная функция возвращает нан (C++)

// 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; 
} 
+0

Просто интересно: Зачем вам нужно делать 'i -' дважды? До 'cout' и после' cout'? –

+0

Спасибо. Я не заметил эту ошибку до сих пор! – Amani

ответ

4

Вы просто забыли return x в конце функции. Компилятор может хранить временные записи в регистре, которые будут содержать возвращаемое значение и заставить его работать.

Вы должны скомпилировать с дополнительными предупреждениями, чтобы компилятор мог рассказать вам о таких вещах.

+0

Он использует глобальный 'float'. В этом случае требуется «возврат»? –

+0

@VusP Он использует возвращаемое значение в 'main()', поэтому да –

+0

Извините, я не понимаю, где я забыл вернуть x. Переменная i должна рассчитывать количество рекурсий. когда i == 0; это когда он должен вернуть значение x. но даже в этом случае я получаю предупреждение «контроль до конца не-пустоты». Благодарю. – Amani

2

И еще одна проблема заключается в следующем: if(i==0), его следует заменить на if(i<=0).

В плавающей области нет понятия равенства, строго говоря. Число в диапазоне - более правильная абстракция. Например, чтобы проверить, является ли f приблизительно равным нулю, вы сделаете так: if(f >= -epsilon && f <= epsilon) ... Где epsilon является либо стандартным FLT_EPSILON, либо некоторой определенной константой точности конкретного приложения.

+0

'В плавающей сфере нет понятия равенства строго говоря. Строго говоря, конечно, есть. Он просто не делает то, что вы думаете в присутствии компьютеров, которые существуют в реальном мире –

Смежные вопросы