4
scanf("%d",&a);
for(b=1;b<=a;++b)
{
    c*=b;
}
printf("%lu",c);

I want to get the answer of 100!
factorial of 100. how can I get this? ( I wanna get a bigger range of numbers) Cant we have the number limit to infinity?

Sparko
  • 735
  • 6
  • 15
user2416353
  • 41
  • 1
  • 1
  • 2
  • 3
    So, what is the point of `c#` and `java` tags? – Soner Gönül Jun 11 '13 at 06:37
  • Assuming you use C# you can read the answer [here](http://stackoverflow.com/questions/10624815/how-can-i-use-bigint-with-c). In Java you can use `java.math.BigInteger`. – Uwe Plonus Jun 11 '13 at 06:38
  • 4
    You can't have infinite integer range, because your computer does not have infinite memory to store it. – Daniel Kamil Kozar Jun 11 '13 at 06:43
  • 1
    100! = 9332621544394415268169923885626670049071596826438162146859 29638952175999932299156089414639761565182862536979208272237582511852109168 64000000000000000000000000. I got it from the code in BLUEPIXY's answer and verified it. –  Jun 11 '13 at 13:07

4 Answers4

23

Max integer range is, on just about every (modern) platform, 2^31 - 1 (although, by the standard, int is only required to be at least 16 bits). For your given platform, it'll be defined as INT_MAX in <limits.h>.

100! will obviously far exceed this. To calculate something this large in C, you'll need a big integer library, such as GMP.

Just as a cautionary note, if you decide to try and use a double (which can hold numbers of this size), you will get the wrong answer due to precision loss. This is easy to spot - on my machine, the last digits are 48, which is obviously nonsense: 100! must be divisible by 100, hence must have 00 as the last two digits.

undur_gongor
  • 15,657
  • 5
  • 63
  • 75
Yuushi
  • 25,132
  • 7
  • 63
  • 81
  • You *can* actually compute it without using GMP library. PostgreSQL supports unlimited precision integer arithmetic. Exact value is here: http://www.sqlfiddle.com/#!12/d41d8/991 – mvp Jun 11 '13 at 07:08
  • 2
    @mvp What does that have to do with being able to compute it in `C`? You can compute it in Python, Lisp, Haskell, Java, C#. None of that means squat if you're limited to `C`. – Yuushi Jun 11 '13 at 07:10
  • I was just having fun. And BTW, PostgreSQL is written in C. So, you can extract unlimited precision functions from its source. – mvp Jun 11 '13 at 07:12
  • It actually ends in 000000000000000000000000 –  Jun 11 '13 at 13:09
6
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#if __STDC_VERSION__>=199901L
#include <inttypes.h>
#else
#define PRIu16 "hu"
#endif

typedef struct _unums {
    size_t size;
    uint16_t *nums;//array 
} UNums;

void UNums_init(UNums *num, uint16_t n){
    num->nums = (uint16_t*)malloc(sizeof(uint16_t));
    num->nums[0] = n;
    num->size = 1;
}

void UNums_mul(UNums *num, uint16_t n){
    uint16_t carry = 0;
    size_t i;

    for(i=0;i<num->size;++i){
        uint32_t wk = n;
        wk = wk * num->nums[i] + carry;
        num->nums[i] = wk % 10000;
        carry = wk / 10000;
    }
    if(carry){
        num->size += 1;
        num->nums = (uint16_t*)realloc(num->nums, num->size * sizeof(uint16_t));
        num->nums[i] = carry;
    }
}

void UNums_print(UNums *num){
    size_t i = num->size;
    int w = 0;
    do{
        --i;
        printf("%0*" PRIu16, w, num->nums[i]);
        if(!w) w = 4;
    }while(i!=0);
}

void UNum_drop(UNums *num){
    free(num->nums);
    num->nums = NULL;
}

int main( void ){
    UNums n;
    uint16_t i;

    UNums_init(&n, 1);
    for(i=2;i<=100;++i)
        UNums_mul(&n, i);
    UNums_print(&n);//100!
    UNum_drop(&n);
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
1

For small numbers you better use unsigned long long than int. But still you have limit on the biggest number you can use for a. You could try double or float but you might get precession error.

Thanushan
  • 532
  • 2
  • 8
1

You can use GMP library

Install with:

sudo apt-get install libgmp3-dev

main.c:

#include <gmp.h>

void f() tooBigForYourShell {
    mpz_t n;                     // declare a big n number
    mpz_init_set_ui(n,0);        // assign 0 as starting value
    mpz_setbit(n, 1UL << 24);    // set bit 2^24 (index 2^24 and not 24...) as 1.
    gmp_printf("%Zd\n", n);      // display the result
}

int main() {
    tooBigForYourShell();
    return 0;
}

Compile with:

gcc main.c -lgmp && ./a.out
???
profit, enjoy your 2^(2^24) number on stdout.

enter image description here NB: There are much more digits before...

You could theoretically go up to 37 used bits (so 2^38 - 1 ?) but beware as it will use a lot of your CPU.

/!\ I AM NOT LIABLE FOR ANY DAMAGE IF YOU GO FOR 2^(2^37).

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81