2013-06-11 3 views
2
scanf("%d",&a); 
for(b=1;b<=a;++b) 
{ 
    c*=b; 
} 
printf("%lu",c); 

Я хочу получить ответ 100!
factorial of 100. Как я могу это получить? (Я хочу получить больший диапазон чисел) К сожалению, у нас есть предел числа до бесконечности?Самое большое число в C

+3

Итак, какова точка 'C#' и 'java' тегов? –

+0

Предполагая, что вы используете C#, вы можете прочитать ответ [здесь] (http://stackoverflow.com/questions/10624815/how-can-i-use-bigint-with-c). В Java вы можете использовать 'java.math.BigInteger'. –

+4

Вы не можете иметь бесконечный целочисленный диапазон, потому что ваш компьютер не имеет бесконечной памяти для его хранения. –

ответ

23

Максимальный целочисленный диапазон, примерно на каждой (современной) платформе, 2^31 - 1 (хотя по стандарту int требуется не менее 16 бит). Для вашей данной платформы она будет определена как INT_MAX в <limits.h>.

100!, очевидно, намного превышает это. Чтобы вычислить что-то такое большое в C, вам понадобится большая целочисленная библиотека, такая как GMP.

Как предостережение, если вы решите попробовать использовать double (который может содержать номера этого размера), вы получите неправильный ответ из-за потери точности. Это легко заметить - на моей машине последние цифры - 48, что явно бессмысленно: 100! должно делиться на 100, следовательно, должно быть 00 в качестве двух последних цифр.

+4

+1 для указания точности потерь и делимости на 100 – exexzian

+0

Вы * можете * фактически вычислить его, не используя библиотеку GMP. PostgreSQL поддерживает неограниченную точность целочисленной арифметики. Точное значение можно найти здесь: http://www.sqlfiddle.com/#!12/d41d8/991 – mvp

+1

@mvp. Какое это имеет отношение к возможности вычислить его в 'C'? Вы можете вычислить его в Python, Lisp, Haskell, Java, C#. Ничто из этого не означает приседания, если вы ограничены 'C'. – Yuushi

1

Для небольших номеров лучше использовать unsigned long long, чем int. Но все же у вас есть ограничение на наибольшее количество, которое вы можете использовать для a. Вы можете попробовать double или float, но вы можете получить ошибку прецессии.

4
#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; 
} 
+0

Слишком плохо Visual Studio не имеет inttypes.h –

+0

@raxman for VC '%% 0 *" PRIu16' -> '"% 0 * hu "' – BLUEPIXY

+0

Спасибо! Я получил его работу, мне пришлось также вызывать функции malloc и realloc. –

Смежные вопросы