Mar 31, 2012 at 10:10pm UTC
Is there anything more precise? I've tried long double, but it's still not enough to calculate 100!, which is ultimately what I need to do.
EDIT: will I need to use arbitrary-precision arithmetic?
Last edited on Mar 31, 2012 at 10:20pm UTC
Mar 31, 2012 at 11:05pm UTC
You don't need to be using floating point variables for factorials. No matter what a factorial is going to be an integer.
You can use unsigned long long, but still probably not long enough for 100!. Or like firedraco said, you can use bignum library.
I seams that unsigned long long will hold up to 65!
Last edited on Mar 31, 2012 at 11:14pm UTC
Apr 1, 2012 at 1:49am UTC
An unsigned long long is 64 bits? The maximum factorial you can get in that is 20!
If your unsigned long long is 128 bits then the maximum you can get in that is 34!
[edit] If you are using floating point numbers you already have only approximations to the correct number after 18!.
[edit 2] I can't resist:
http://www.cplusplus.com/forum/lounge/32041/
Last edited on Apr 1, 2012 at 1:52am UTC
Apr 1, 2012 at 2:54am UTC
Thanks for all of the replies.
@firedraco, I probably will have to use a bignum library eventually but for now I want to try to find my own solution. The reason I am doing this is actually to solve problem 20 of project euler.
@iseeplusplus, unsigned long long seems to have less precision when I try it.
@ Duoas, thanks for the link, but I don't want to look at that thread quite yet. First I want to see if I am in the right direction with the following source code, which I have spent the last few hours writing. It's ugly and it doesn't seem to work well though.
EDIT: Nevermind, I finally got it to work. Here's my finished code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#include <iostream>
#include <cmath>
#include <vector>
#include <sstream>
#include <iomanip>
#include <limits>
int main()
{
int i;
std::stringstream ss;
std::string s,product="100" ;
std::string multiply(std::string a,std::string b);
for (i=100;i>1;i--)
{
ss<<i-1;
ss>>s;
ss.clear();
product=multiply(product,s);
}
std::cout<<product<<std::endl;
std::cout<<std::endl<<"Press ENTER to continue..." ;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n' );
return 0;
}
std::string multiply(std::string a,std::string b)
{
int i,j,k,digit1,digit2,carry=0,sum=0;
std::stringstream ss;
std::string s,product;
std::vector<std::vector<int > >rows;
std::vector<int >row;
std::vector<int >reverseProduct;
for (i=(int ) b.size()-1,k=0;i>=0;i--,k++)
{
for (j=0;j<k;j++)
row.push_back(0);
for (j=(int ) a.size()-1;j>=0;j--)
{
ss<<b[i]<<" " <<a[j];
ss>>digit1>>digit2;
ss.clear();
row.push_back((digit1*digit2+carry)%10);
carry=floor((digit1*digit2+carry)/10);
}
if (carry!=0)
{
row.push_back(carry);
carry=0;
}
rows.push_back(row);
row.clear();
}
for (i=0;i<(int ) rows.size()-1;i++)
{
k=rows[rows.size()-1].size()-(int ) rows[i].size();
for (j=0;j<k;j++)
rows[i].push_back(0);
}
carry=0;
for (j=0;j<(int ) rows[0].size();j++)
{
for (i=0;i<(int ) rows.size();i++)
sum+=rows[i][j];
reverseProduct.push_back((sum+carry)%10);
carry=floor((sum+carry)/10);
sum=0;
}
if (carry!=0)
reverseProduct.push_back(carry);
for (i=(int ) reverseProduct.size()-1;i>=0;i--)
ss<<reverseProduct[i];
ss>>product;
return product;
}
Last edited on Apr 1, 2012 at 6:31am UTC