# Thread: C Newbie Problem with Factorial Example

1. ## C Newbie Problem with Factorial Example

Can anyone please help me with my logic here , i can't seem to figure it out, however when i try to find Factorial of num 2 i get the factorial as 2 which is right , but other numbers give me huge negative numbers , WHY ??
please point out my mistake so i can learn , any help appreciated
Thank you

Have a nice day!
I'm trying to learn C on my own , i won't give up this time so many times i've tried and gave up half-way especially when i start pointers, will you guys help me !!!

Code:
```#include<stdio.h>
int fact();

int main() {

int n,res;
printf("Enter a Factorial :\n");
scanf("%d",&n);

res = fact(n);
printf("The Factorials of %d = : %d \n",n,res);

return 0;

}

int fact(int num)
{
int i=1;
if(num == 0) {
num =1;
}else{
while(num >i) {
num = num *i;
i++;
}

}
return num;
}
``` 2. This Seems to Work

Code:
```int fact(int num)
{
int i=1;
int fact =1;
if(num == 0) {
num =1;
}else{
for(i=num;i>=1;i--)
{
fact = fact * i;
}

}
return fact;
}``` 3. Hi nerx!

The second way to do it is:
Code:
```#include <stdio.h>

int fact(int num); // don't forget the right declaration

int main(int argc, char **argv)
{
int n,res;

printf("Enter a Factorial: ");
scanf("%d",&n);

res = fact(n);
printf("The Factorials of %d = %d\n",n,res);

return 0;
}

int fact(int num)
{
int i = 1, result = 1;

if(num == 0)  num = 1;
else while(num > i) result *= ++i;

return result;
}```
On my system the limit is by 20! =2.4329e+18
but with your program the result is with greater than 20 wrong.
The storage size of int is 4 byte.
If you would take the data type long the storage size would be 8 byte.

I know it is not really proper to change the data type to long double.
With this you would turn the number of factorials up to 1500!

example:
Code:
```#include <stdio.h>

long double fact(long double num);

int main(int argc, char **argv)
{
long double n, res;

printf("Enter a Factorial: ");
scanf("%Lf",&n);

res = fact(n);
printf("The Factorials of %Lf = %Lf\n", n, res);

return 0;
}

long double fact(long double num)
{
long double i = 1, result = 1;

if(num == 0)  num = 1;
else while(num > i) result *= ++i;

return result;
}``` 4. A simpler function:
Code:
```int factorial( int x )
{
int r = 1;

while ( x > 1 )
r *= x--;

return r;
}```
@rusyoldguy is right to think about limits. An 'int' is, typically, 31 bits precision integer (the 32nd bit is used as signal), so, the maximum factorial you'll be abble to get is 12! (479001600, 29 bits long), since 13! is 6227020800 (33 bits long).

The function above allows for greater values of x, but you'll get overflow in your hands...

To use floating point isn't acceptable, since the greater the value, less exact it is... The precision of floating point types is measured in bits (as the integer values are)... float has 24 bits of precision; double, 53; long double, 64; and the non standard __float128, 113 (requires libquadmath to print the value)...
So, 100! has 525 bits and cannot be expressed exactly in floating point:
Code:
```\$ bc -ql
define l2(x){return l(x)/l(2)}
define fact(x){if (x < 2) return 1; return x*fact(x-1);}
fact(100)
93326215443944152681699238856266700490715968264381621468592963895217\
59999322991560894146397615651828625369792082722375825118521091686400\
0000000000000000000000
l2(fact(100))
524.76499329005968632625```
You can use multiple precision libgmp library, but it is not so direct as using 'int' ou derivatives...

Let's see @rusyoldguy example os 20!
Code:
```\$ bc -ql
/* define l2() and fact() again here */
fact(20)
2432902008176640000
l2(fact(20))
61.07738392090622137726```
Ok... it has 62 bits, representable in long double... But not 21!
Code:
```l2(fact(21))
65.46970134368498166621```
But it is representable in __float128 (which, in theory, will support up to 31!):
Code:
```l2(fact(31))
112.66326365236030334343```
Yes, of couse you can use another non standard type: __int128 (with 127 bits of precision), which will support 33!, maximum... But also requires libquadmath to be printed.

if you use 'unsiged __int128' you can get up to 34! Popular pages Recent additions factorial, int, learn, num, return 