ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Warg,
You have a few cast converstion problems going on there. The most drastic is that e is declared as a double instead of a long double. You going to loose precision each time you return from fact because your putting a long double result into a double variable.
I've made a few changes that make it better... though you probably want to get a high precision math library if you really need that much precision.
Thanks. The changes didn't add much precision but it's still better. I'm supposed to stick only to the very basic fundamentals of C and arithmetics so math libraries are not an option, though I too doubt I'll get a more precise output with the current method.
Well 100! is a large number it has about 160 digits. Therefore the reciprocal will have about 160 zeros before it starts to have any significance. Since you are only concerned with 40 digits, 100! is overkill.
Secondly n! = n(n-1)! You can use that to refrain from having to recalculate all the elements of n! each time.
Excuse my ignorance but I still don't understand. Apart from reducing the cpu cycles needed for running the program, will your suggestion actually affect the precision of the output? If so, how?
EDIT:
By the way, I used this formula for the calculation (if it wasn't obvious already). It's supposed give the precise value of e (by "precise" I mean as precise as it can get).
My main comment is about reducing the cpu cycles. However there may be a small increase in accuracy because of a possible reduction of rounding errors (sorry it's too early in the morning to think properly )
Your restriction on precision is going to be the number of digits a long double can actually hold, and if you need more accuracy then you would benefit from switching to a scientific library that is designed to hold a large number of digits.
I hope that helps and sorry if I was a little misleading with my comments.
My main comment is about reducing the cpu cycles. However there may be a small increase in accuracy because of a possible reduction of rounding errors (sorry it's too early in the morning to think properly )
Your restriction on precision is going to be the number of digits a long double can actually hold, and if you need more accuracy then you would benefit from switching to a scientific library that is designed to hold a large number of digits.
I hope that helps and sorry if I was a little misleading with my comments.
graeme
I just noticed something. You mentioned 1/35! will have 40 zeros, which is correct. But, whatever I set the upper limit of the variable "counter", as long as it's above 21, the program gives the very same result. And of course, it doesn't seem to have anything to do with the limitations of long double. Could anyone enlighten me please?
I'm sure that it is to do with a limitation on the number of digits that a long double can hold. You've essentially hit the limit and if you need more accuracy then you will need to look at using a scientific library or creating your own datatype to hold the number required.
I'm sure that it is to do with a limitation on the number of digits that a long double can hold. You've essentially hit the limit and if you need more accuracy then you will need to look at using a scientific library or creating your own datatype to hold the number required.
graeme.
I don't think so. I used to factorial function as a stand-alone program, even made it to print 1.0/fact(k) and the output was accurate, and the limitation was way beyond 1.0/40!.
The following is some C++ code and illustrates the difference between precision and number of digits when using the data type double
Code:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[])
{
numeric_limits<long double> nlld;
cout << "Numeric limit of a long double\n"
<< "The number of digits: " << nlld.digits10 << "\n"
<< "max exponent: " << nlld.max_exponent10 << "\n";
numeric_limits<double> nld;
cout << "Numeric limit of a double\n"
<< "The number of digits: " << nld.digits10 << "\n"
<< "max exponent: " << nld.max_exponent10 << "\n";
system("PAUSE");
return 0;
}
When I ran on my machine using the g++ compiler (for windows) I had the following results
Code:
Numeric limit of a long double
The number of digits: 18
max exponent: 4932
Numeric limit of a double
The number of digits: 15
max exponent: 308
Press any key to continue . . .
This shows that I have 18 digits available even though it can hold the number to much greater precision using the exponent.
Maybe I didn't make myself clear. Look at this code:
Code:
#include <stdio.h>
main()
{
long double n, sum;
scanf("%Lf", &n);
sum = n;
while(n != 1)
{
sum = sum * (n - 1);
n = n - 1;
}
printf("%.40Lf\n", 1.0/sum);
}
The output for n = 20 is 0.0000000000000000004110317623312164858406. For 30 it is 0.0000000000000000000000000000000037699876.
Now, I use the exact same function in my e calculation program...
Code:
#include <stdio.h>
long double fact(long double n)
{
long double sum;
sum = n;
if(n == 0)
return 1;
else
{
while(n != 1)
{
sum = sum * (n - 1);
n = n - 1;
}
return sum;
}
}
main()
{
int counter;
long double e, k;
k = e = 0;
for(counter = 0; counter < 21; counter++)
{
e = e + (1.0/fact(k));
++k;
}
printf("%.40Lf\n", e);
}
Output when counter is set to 20 is:
2.7182818284590452349944872389997385653260.
For 21 it is:
2.7182818284590452354281681079939403389290.
For 30 it is:
2.7182818284590452354281681079939403389290
As you can see, 1/30! is far below long double's limitation, but the program prints the same result as long as counter is above 21.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.