So I\'m learning C++. I\'ve got my \"C++ Programming Language\" and \"Effective C++\" out and I\'m running through Project Euler. Problem 1...dunzo. Problem 2...not so mu
Break the code for generatring, at times float number dont behave the way we think when used in a long expression...break the code and check it.
I agree 100% with shog9's answer - with the algorithm you used to calculate Fibonacci, you have to be really careful with floating point values. I found that the page cubbi.com: fibonacci numbers in c++ seems to show other ways of obtaining them.
I looked around for a good idea on how to make your implementation of GenerateNthFibonacciNumber handle cases where it returns the double 54.999999, but when you cast to an int or a long you get 54.
I came across what appears to be a reasonable solution at C++ Rounding, which I have adapted below in your code.
Also, It's not a huge deal, but you may want to precalculate PHI, then either pass it as a parameter or reference it as a global - now you are recalculating it every time you call the function.
double GenerateNthFibonacciNumber(const int n)
{
//This generates the nth Fibonacci Number using Binet's Formula
const double PHI = (1.0 + sqrt(5.0)) / 2.0;
double x = ((pow(PHI,n)-pow(-1.0/PHI,n)) / sqrt(5.0));
// inspired by http://www.codingforums.com/archive/index.php/t-10827.html
return ((x - floor(x)) >= 0.5) ? ceil(x) : floor(x);
}
Finally, here's how I rewrote your Solve() method so that GenerateNthFibonacciNumber(FibIndex) is only called in one place in the code. I also added the column with the current running total of the even Fibonacci terms to your output:
double Solve() {
long FibIndex = 0;
double result = 0.0;
double oldresult = 0.0;
int done = 0;
const double PHI = (1.0 + sqrt(5.0)) / 2.0;
while (!done)
{
double currentFib = GenerateNthFibonacciNumber(++FibIndex);
if ((int)currentFib % 2 == 0)
{
oldresult = result;
if (currentFib >= 4000000.0)
{
done = 1;
}
else
{
result += currentFib;
}
}
cout << currentFib << " " << (int)currentFib << " " << (int)currentFib % 2 << " " << (int)result << "\n";
}
return result;
}