C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
I was talking to the original poster, and I never said I was a nut, but I am saying I am not wrong. The OP asked how come his output was wrong, and I am stating why.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
Well I am a nut. And its all good. I took out my calculator and tried some stuff with his equation by hand, and it doesn't even calculate the third number correctly
Good for you. I couldn't even get it to compile since M_E is undefined for meI took out my calculator and tried some stuff with his equation by hand, and it doesn't even calculate the third number correctly
That said, going by the webpage referenced, the formula is correct (though that webpage's formula is itself an approximation, not the full formula).
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
#include <math.h>, laserlight. I will double check, but unless I did something else wrong, I didn't get the formula to work correctly. The point is moot though, since its not the most efficient way of solving this. Plus it would only be beneficial to use a formula like this to solve an arbitrarily high number, which cannot be done due to accuracy issues, apparently.
[edit]Wtf... *#include <float.h> I mean[/edit]
I am still not getting this to work. I get what the derivation is saying and all, and it looks fascinating. Perhaps I am just not doing it correctly. asinh() is a bastard to do on my calc.. But still, I did it correctly -_-
Perhaps you would like to try this, using just square root computation instead of a trigonometric function:I will double check, but unless I did something else wrong, I didn't get the formula to work correctly.
Ideally, we should only compute sqrt5 and phi once, but anyway...Code:#include <math.h> #include <stdio.h> unsigned int fib(unsigned int n) { double sqrt5 = sqrt(5.0); double phi = (1.0 + sqrt5) / 2.0; return (unsigned int)((pow(phi, n) / sqrt5) + 0.5); } int main(void) { int x; for (x = 0; x < 48; ++x) { printf("%u: %u\n", x, fib(x)); } return 0; }
That depends on what factors you are considering for efficiency.The point is moot though, since its not the most efficient way of solving this.
Yes, and it is not as efficient as memoization when you want to generate all the Fibonacci numbers up to some limit, like what cph was trying to do.Plus it would only be beneficial to use a formula like this to solve an arbitrarily high number, which cannot be done due to accuracy issues, apparently.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
You know what laserlight, I had an unfortunate IO error (That would be "Idiot Operator" not "Input/Output"). Yeah it works fine.. I am just a boob sometimes.
And yeah I tried the non-trigonometric version when I was looking at the derivation which is why I wasn't following how come my results weren't working. But it works fine.
64-bit numbers?Originally Posted by cph
GMP?
You are asking how to reach above and beyond a hardware limitation. You are asking how to make your computer do something that is beyond the implementation of your algorithm. Right? I mean you see how I arrive at that conclusion, right?
Order of evaluation and associativity are not the same thing. However, I think that matsp is wrong - there is no undefined behaviour as far as I can tell. I recall a thread some time ago where the conclusion was that the XOR swap of a and b written as a ^= b ^= a ^= b; resulted in undefined behaviour, but I believe that is because a is modified twice within consecutive sequence points. In your code, however, both a[0] and a[1] are modified exactly once within consecutive sequence points.Originally Posted by nonoob
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Thanks for that explanation, laserlight. i was starting to get worried that I am misunderstanding associativity in any standard precedence chart. What is it then if "right-to-left" is not related to execution order? The right argument is evaluated first, I thought.
The order of evaluation of operands is unspecified. In this case, it does not matter, but consider this contrived example:Originally Posted by nonoob
It is possible that on one implementation the output is "1\n2\n3\n" while on another it is "3\n2\n1\n".Code:#include <stdio.h> int *foo(int *x, int y) { printf("%d\n", y); return x; } int main(void) { int a = 1; int b = 2; *foo(&a, 1) += *foo(&b, 2) += *foo(&a, 3); return 0; }
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Sorry to bump an old thread, but I came accross this accidentally and wanted to share my thoughts.
First of all, the problem with this method posted above:is that it's simply incorrect, or incomplete. It's only half of the Fibonacci recurrence relation.Code:pow(PHI, n) / sqrt(5.0)
The correct way would be:(use long long instead of int for large n, as the result will obviously not fit in 32 bit integers).Code:int Fib( int n ) { static const double s = sqrt(5.0); return int( (pow(1+s,n)-pow(1-s,n))/(pow(2.0,n)*s) ); }
There is, however, an even much faster way. After quite some experimenting with several approaches and lotsa optimizing, this is imho the ultimate solution: (besides using a direct lookup or caching table of course)This performs about 3 times as fast as the pow / √5 method. Of course, again, use long long for large n.Code:unsigned int Fib( unsigned int n ) { n--; unsigned int a=1,b=0,c=1,p=1,t; while (p<=n) p += p; do { p >>= 1; t = b*b; b *= a+c; a = a*a + t; c = c*c + t; if (n&p) { c = b; b = a; a += c; } } while (p>1); return a; }
That is okay; I maintain that it is fine to post in an ancient thread when you have something worthwhile to contribute, especially if it is an important correction.Originally Posted by Phuzzillogic
It is not incorrect in its idea since the idea is that the other half can be ignored as it has negligible contribution in the approximation. I demonstrated a correct way to perform this approximation in post #45.Originally Posted by Phuzzillogic
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)