когда я использую цикл while, функция возвращает правильное значение, но когда я делаю функцию рекурсивной, она возвращает nan. Для целей отладки, я выслал значение (x) непосредственно перед его возвратом и дал правильный ответ, но после возвращения значения вызывающей функции это нан. Еще одна вещь, программа не принимает 0 для коэффициентов x. Любые попытки приводят к нан. Ниже мой код (все это, чтобы быть уверенным, что я не дал недостаточно информации):
// 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 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;
}
Вы просто забыли return x
в конце функции. Возможно, компилятор должен хранить временные записи в регистре, которые будут содержать возвращаемое значение и заставить его работать.
Вы должны скомпилировать с большим количеством предупреждений, чтобы компилятор мог рассказать вам о таких вещах.
float
. Необходим ли return
в этом случае?
main()
, так что да
И еще одна проблема заключается в этом утверждении: if(i==0)
, его следует заменить на if(i<=0)
.
В плавающей сфере нет понятия равенства, строго говоря. Число в диапазоне - более правильная абстракция. Например, чтобы проверить, является ли значение f
приблизительно равным нулю, вы должны сделать это: if(f >= -epsilon && f <= epsilon)...
Где epsilon
является либо стандартным FLT_EPSILON, либо некоторой определенной константой точности приложения.
In float realm there is no concept of equality strictly speaking.
Строго говоря, конечно, есть. Он просто не делает то, что вы думаете, в присутствии компьютеров, которые существуют в реальном мире
i--
дважды? Доcout
и послеcout
?