crecursioncodeblocksfactorialunsigned-long-long-int

why it gives negative values when finding factorial in C?


#include <stdio.h>
#include <math.h>

unsigned long int factorial_rec(unsigned long n)
{
  if(n==1) return 1;
  else return factorial_rec(n-1) * n;
}

int main(int argc, char **argv)
{
  int i;

  for(i=1; i<30; i++)
    printf("%d! = \t%d\n", i, factorial_rec(i));

  return 0;
}

Output :-

1! =    1
2! =    2
3! =    6
4! =    24
5! =    120
6! =    720
7! =    5040
8! =    40320
9! =    362880
10! =   3628800
11! =   39916800
12! =   479001600
13! =   1932053504
14! =   1278945280
15! =   2004310016
16! =   2004189184
17! =   -288522240
18! =   -898433024
19! =   109641728
20! =   -2102132736
21! =   -1195114496
22! =   -522715136
23! =   862453760
24! =   -775946240
25! =   2076180480
26! =   -1853882368
27! =   1484783616
28! =   -1375731712
29! =   -1241513984

Solution

  • The main problem is how you're printing the results:

    printf("%d! = \t%d\n", i, factorial_rec(i));
    

    The %d format specifier expects an int argument, but for the second one you're passing in an unsigned long. Using the wrong format specifier invokes undefined behavior.

    For an unsigned long you should use %lu as the format specifier. However, an unsigned long is not guaranteed to be big enough to hold a 64-bit number. For that, you should use unsigned long long as the datatype, and use %llu to print it.