Hmm ... start by writing a recurisve function to find the factorial of a number. There's a tutorial on recursion in either the C++ or the Computer Science section of this site - I forget which. You should also be able to find this function by doing a quick google search. Then just add 1/ to your factorial equation and it should do the trick ;)
cscgal
The Queen of DaniWeb
19,422 posts since Feb 2002
Reputation Points: 1,474
Solved Threads: 230
>how do you get to calculae a power. is it pow(...)
Yes, that's one way.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>for ( int i = 1; i < 4000; i++ ) {
>e += 1.0 / fakt(i);
Wow, I'm impressed if you can fit up to 3999! into a double. I just get undefined behavior when the limit of double is exceeded. :rolleyes:
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>but with my compiler the result is still correct
That's nice, but your code is still wrong even if the compiler that you use happens to interpret "undefined" as something intelligent.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>explain why I did not recognize the mistake in the first place.
I can understand not knowing that floating-point overflow is undefined, but it should be immediately obvious that a double couldn't possibly hold a factorial anywhere close to 3999!.
>but code snippets should be seen as starting points or suggestions, not finished product.
I agree. Unfortunately, those that we help aren't quite so forgiving. They have a tendency to see code we post as set in stone answers that "must" be correct. As such, rather than end up teaching bad habits, we should try to be as accurate and correct as possible.
>None of the snippets or suggestions I make are ones I've built and tested
That's your choice. I prefer to only post code that I've made sure works as expected. However, you should mention that your code wasn't tested and you only "hope" that it works.
>only ideas to get the thread-opener's juices flowing.
That's fine, I do it myself. But I make sure that the example is still correct so that the juices aren't sour.
>Some of my posts have been nit picked for syntax or stuff that misses the bigger picture
That's a rather narrow view I think. It seems to me that it was you who missed the bigger picture. If you don't want to be nitpicked on syntax then give pseudocode. It still conveys the idea and avoids people like me who think that teachers should make an attempt at being correct because they're viewed as role models.
>but please try to have a little patience with those of us who can't devote as much time to posts as you.
I have very little time to devote to posts despite what you may think, but I still manage to check my answers. Thus I have very little patience for people who are either too lazy or too arrogant to make sure that they're right.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>sorry for beeing that stupid.
I wouldn't say stupid because that would be mean without being constructive. But it is always a good idea to know what the limitations of your system are, and even better the limitations placed on you by the language standard. Then you can more easily determine if you exceed those limitations using common sense. It seems to me that the problem was just a lack of information concerning the size of a double. The fact that your implementation didn't throw a floating-point exception but instead did something nice didn't help at all. It just hid the fact that your code was doing something it wasn't supposed to do.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>What I underestimated ( quite a lot I must admit ) is the level of recoursion that occurs in computing the factorial of a number.
Factorials grow incredibly fast. Whenever you have a sequence like that, you need to be aware of your limits. :)
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
I've been playing along at home; any criticisms for this?
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <limits.h>
int factorial(unsigned long n, unsigned long *result)
{
unsigned long i;
for ( *result = 1, i = 2; i <= n; i++ )
{
if ( *result > ULONG_MAX / i )
{
printf("overflow at n = %lu, ", n);
return 0;
}
*result *= i;
}
//printf("n = %lu, result = %lu\n", n, *result);
return 1;
}
double estimate_e(unsigned long iterations)
{
double e = 1.0;
unsigned long i, denominator;
for ( i = 1; i < iterations && factorial(i, &denominator); ++i )
{
e += 1.0 / denominator;
}
return e;
}
int main()
{
double epsilon = 1E-10; /* or specify your own pickiness level */
double e = exp(1.0);
unsigned long i;
for ( i = 0; i < 20; ++i )
{
double estimate = estimate_e(i);
printf("estimate_e(%2d) = %.*g\n", i, DBL_DIG, estimate);
if ( fabs(e - estimate) <= epsilon * fabs(e) )
{
puts("close enough");
break;
}
}
printf("e = %.*g\n", DBL_DIG, e);
return 0;
}
/* my output
estimate_e( 0) = 1
estimate_e( 1) = 1
estimate_e( 2) = 2
estimate_e( 3) = 2.5
estimate_e( 4) = 2.66666666666667
estimate_e( 5) = 2.70833333333333
estimate_e( 6) = 2.71666666666667
estimate_e( 7) = 2.71805555555556
estimate_e( 8) = 2.71825396825397
estimate_e( 9) = 2.71827876984127
estimate_e(10) = 2.71828152557319
estimate_e(11) = 2.71828180114638
estimate_e(12) = 2.71828182619849
estimate_e(13) = 2.71828182828617
close enough
e = 2.71828182845905
*/
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
>any criticisms for this?
You code looks a lot like C but you use the single line comment style without mentioning C99. ;) Other than that I have no criticisms except for the use of epsilon instead of DBL_EPSILON. Your value of 1E-10 exceeds the standard minimum requirement by 1 IIRC, so it isn't technically portable.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>>any criticisms for this?
>You code looks a lot like C
It is.
>but you use the single line comment style without mentioning C99. ;)
True enough. I came back to edit that debug line out, but chose not to.
>Other than that I have no criticisms except for the use of epsilon instead of DBL_EPSILON.
I had initially used DBL_EPSILON, but the results are the other way.:D
estimate_e( 0) = 1
estimate_e( 1) = 1
estimate_e( 2) = 2
estimate_e( 3) = 2.5
estimate_e( 4) = 2.66666666666667
estimate_e( 5) = 2.70833333333333
estimate_e( 6) = 2.71666666666667
estimate_e( 7) = 2.71805555555556
estimate_e( 8) = 2.71825396825397
estimate_e( 9) = 2.71827876984127
estimate_e(10) = 2.71828152557319
estimate_e(11) = 2.71828180114638
estimate_e(12) = 2.71828182619849
estimate_e(13) = 2.71828182828617
overflow at n = 13, estimate_e(14) = 2.71828182828617
overflow at n = 13, estimate_e(15) = 2.71828182828617
overflow at n = 13, estimate_e(16) = 2.71828182828617
overflow at n = 13, estimate_e(17) = 2.71828182828617
overflow at n = 13, estimate_e(18) = 2.71828182828617
overflow at n = 13, estimate_e(19) = 2.71828182828617
e = 2.71828182845905That's another reason I added the comment, "or specify your own pickiness level".
>Your value of 1E-10 exceeds the standard minimum requirement by 1 IIRC, so it isn't technically portable.
This is new to me... could you expand on this please?
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314