# Fibonacci Program

Discussion in 'C++' started by Protoman, May 28, 2006.

1. ### ProtomanGuest

This Fibonacci program prints the wrong value for phi; it should be
1.618..., not 1. And it halts and closes as soon as I execute it.

Code:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#define setprec setprecision
using namespace std;

template <long long N> class FIB
{
public:
const static long long RET=FIB<N-1>::RET+FIB<N-2>::RET;
};
template<>class FIB<2>
{
public:
const static long long RET=1;
};
template<>class FIB<1>
{
public:
const static long long RET=1;
};
template<>class FIB<0>
{
public:
const static long long RET=0;
};
long double phi=FIB<10>::RET/FIB<9>::RET;
int main()
{
cout << "Fib(30)=" << setprec(10) << fixed << FIB<10>::RET << endl;
cout << "Fib(29)=" << setprec(9) << fixed << FIB<9>::RET << endl;
cout << "Phi= " << setprec(30) << fixed << phi << endl;
system ("PAUSED");
return 0;
}

Any guesses as to what's wrong, b/c I can't detect any errors?
Thanks!!!!

Protoman, May 28, 2006

2. ### Ian CollinsGuest

Protoman wrote:
> This Fibonacci program prints the wrong value for phi; it should be
> 1.618..., not 1. And it halts and closes as soon as I execute it.
>

> long double phi=FIB<10>::RET/FIB<9>::RET;

You have an integer type divided by another. These should be converted
to long doubles.

double f10 = FIB<10>::RET;
double f9 = FIB<9>::RET;
long double phi= f10/f9;

> int main()
> {
> cout << "Fib(30)=" << setprec(10) << fixed << FIB<10>::RET << endl;
> cout << "Fib(29)=" << setprec(9) << fixed << FIB<9>::RET << endl;
> cout << "Phi= " << setprec(30) << fixed << phi << endl;
> system ("PAUSED");

What's this supposed to do?

> return 0;
> }

--
Ian Collins.

Ian Collins, May 28, 2006

3. ### Jonathan McdougallGuest

Protoman wrote:
> This Fibonacci program prints the wrong value for phi; it should be
> 1.618..., not 1. And it halts and closes as soon as I execute it.
>
> Code:
>
> #include <iostream>
> #include <iomanip>
> #include <cstdlib>
> #define setprec setprecision

Don't do that, it gives you nothing, is dangerous and confuses other
programmers.

> using namespace std;

http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5

> template <long long N> class FIB

long long does not exist in standard C++.

> {
> public:
> const static long long RET=FIB<N-1>::RET+FIB<N-2>::RET;

I am not sure whether this is legal or not and I found nothing in
c.l.c++ and c.std.c++ after a quick search. Comeau issues the warning
"storage class is not first", although the standard does not seem to
mandate any order for decl-specifier's. Perhaps someone could confirm
this.

In any case, I would recommend this:

static const long ...

> };
> template<>class FIB<2>
> {
> public:
> const static long long RET=1;
> };
> template<>class FIB<1>
> {
> public:
> const static long long RET=1;
> };
> template<>class FIB<0>
> {
> public:
> const static long long RET=0;
> };
> long double phi=FIB<10>::RET/FIB<9>::RET;

FIB::RET is an integer, so this is an integer division, truncating the
fraction part. Therefore, it gives "1". Replace this by

double phi=static_cast<double>(FIB<10>::RET) / FIB<9>::RET;

And long double is also not standard.

> int main()
> {
> cout << "Fib(30)=" << setprec(10) << fixed << FIB<10>::RET << endl;
> cout << "Fib(29)=" << setprec(9) << fixed << FIB<9>::RET << endl;
> cout << "Phi= " << setprec(30) << fixed << phi << endl;
> system ("PAUSED");

system() is standard, but what goes in it is not. You seem to think
"PAUSED" on your system has some effect and that it is the effect you
desire. You also seem to be wrong. Perhaps

std::cin.get();

could help you more, if the problem is to keep a "console window"
opened.

> Any guesses as to what's wrong, b/c I can't detect any errors?

This is not a chat room, try to type complete words.

Jonathan

Jonathan Mcdougall, May 28, 2006
4. ### ProtomanGuest

OK, I replaced it, and it works:

long double phi=static_cast<long double>(FIB<11>::RET)/static_cast<long
double>(FIB<10>::RET);

And I made a spelling error in the system() call, which is why it kept
abending.

And, since this is a TMP program, could you tell me what the code the
compiler collaspses the metaprogram into is? Thanks!!!!

Protoman, May 28, 2006
5. ### Thomas J. GritzanGuest

Protoman schrieb:
> OK, I replaced it, and it works:

Was did you replace? What is _it_?

> long double phi=static_cast<long double>(FIB<11>::RET)/static_cast<long
> double>(FIB<10>::RET);
>
> And I made a spelling error in the system() call, which is why it kept
> abending.
>
> And, since this is a TMP program, could you tell me what the code the
> compiler collaspses the metaprogram into is? Thanks!!!!

Well, on my system, the line

double phi = static_cast<double>(fib<11>::result)/fib<10>::result;

translates into something like this:

double phi = 1.618181818; // maybe more precision

What did you expect?

Thomas

Thomas J. Gritzan, May 28, 2006
6. ### GregGuest

Jonathan Mcdougall wrote:
> Protoman wrote:
> > This Fibonacci program prints the wrong value for phi; it should be
> > 1.618..., not 1. And it halts and closes as soon as I execute it.
> >
> > Code:
> >
> > #include <iostream>
> > #include <iomanip>
> > #include <cstdlib>
> > #define setprec setprecision

>
> Don't do that, it gives you nothing, is dangerous and confuses other
> programmers.
>
> > using namespace std;

>
> http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5
>
> > template <long long N> class FIB

>
> long long does not exist in standard C++.
>
> > {
> > public:
> > const static long long RET=FIB<N-1>::RET+FIB<N-2>::RET;

>
> I am not sure whether this is legal or not and I found nothing in
> c.l.c++ and c.std.c++ after a quick search. Comeau issues the warning
> "storage class is not first", although the standard does not seem to
> mandate any order for decl-specifier's. Perhaps someone could confirm
> this.
>
> In any case, I would recommend this:
>
> static const long ...
>
>
> > };
> > template<>class FIB<2>
> > {
> > public:
> > const static long long RET=1;
> > };
> > template<>class FIB<1>
> > {
> > public:
> > const static long long RET=1;
> > };
> > template<>class FIB<0>
> > {
> > public:
> > const static long long RET=0;
> > };
> > long double phi=FIB<10>::RET/FIB<9>::RET;

>
> FIB::RET is an integer, so this is an integer division, truncating the
> fraction part. Therefore, it gives "1". Replace this by
>
> double phi=static_cast<double>(FIB<10>::RET) / FIB<9>::RET;
>
> And long double is also not standard.

The long double type is a standard C++ floating point type (double and
float are the other two). See ยง3.9.1/8. Furthermore, the long long
type has been added to the forthcoming C++ standard. But many C++
compilers support it already since long long is a standard type in C99.

Greg

Greg, May 28, 2006
7. ### ProtomanGuest

Thomas J. Gritzan wrote:
> Protoman schrieb:
> > OK, I replaced it, and it works:

>
> Was did you replace? What is _it_?
>
> > long double phi=static_cast<long double>(FIB<11>::RET)/static_cast<long
> > double>(FIB<10>::RET);
> >
> > And I made a spelling error in the system() call, which is why it kept
> > abending.
> >
> > And, since this is a TMP program, could you tell me what the code the
> > compiler collaspses the metaprogram into is? Thanks!!!!

>
> Well, on my system, the line
>
> double phi = static_cast<double>(fib<11>::result)/fib<10>::result;
>
> translates into something like this:
>
> double phi = 1.618181818; // maybe more precision
>
> What did you expect?
>
> Thomas

A mov instruction.

Protoman, May 28, 2006