简体   繁体   中英

The biggest number in C

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?

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.

#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;
}

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.

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.

在此处输入图片说明 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM