El progtwig no devuelve la salida para un valor de entrada grande, como 50. Devuelve 0. este es un progtwig factorial que usa la recursión

/*Program to find factorial of a number using recursion*/ #include #include /*Function to recursively compute factorial of a number*/ long int fact(long int n) { if(n==0) return 1; return n*fact(n-1); } int main() { long int n; printf(" enter n "); scanf("%ld",&n); printf ("%ld",fact(n)); return 0; } 

50! es un número muy grande (más de 60 dígitos) y 2^64 es menos de 50! . La razón por la que no obtiene el número correcto es que se desborda , está contando por encima del límite de lo que su computadora puede calcular.

 enter n 50 -3258495067890909184 

Si tiene un número entero de 64 bits, el valor más grande que puede representar es 2 ^ 64, que es más pequeño que 50 !. Por lo tanto se obtiene desbordamiento.

Normalmente, en estas situaciones recurre a algún truco, similar a un sistema de 4 bits que ejecuta un código de 8 bits duplicando el número de instrucciones por palabra (la forma en que la primera CPU de Intels tenía un código de 8 bits).

Entonces, su sistema de 64 bits realmente puede manejar palabras de 128 bits, solo tiene que escribir un algoritmo que ponga los datos en “trozos” para que pueda duplicar la longitud de su palabra.

50! es 30414093201713378043612608166064768844377641568960512000000000000 o aproximadamente 3.04e+64 , un número de 215 bits. Este valor normalmente excede el rango de tipos como el long . Incluso uintmax_t y unsigned long long solo necesitan ser capaces de representar al menos enteros de 64 bits.

 long int fact(long int n) { ... // Overflows! return n*fact(n-1); 

Para obtener una respuesta exacta, el código podría usar tipos alternativos. Lo siguiente utiliza una cadena / representación decimal de un entero. Funciona para valores grandes de n ya que la funcionalidad correcta está limitada por el tamaño del búfer.

 char *strfact_mult(char *s, unsigned x) { unsigned sum = 0; size_t len = strlen(s); size_t i = len; while (i > 0) { sum += (s[--i] - '0')*x; s[i] = sum%10 + '0'; sum /= 10; } while (sum) { len++; memmove(&s[1], s, len); s[i] = sum%10 + '0'; sum /= 10; } return s; } char *str_fact(char *dest, unsigned n) { strcpy(dest, "1"); while (n > 1) { strfact_mult(dest, n--); } return dest; } int main(void) { char buf[1000]; puts(str_fact(buf, 0)); puts(str_fact(buf, 1)); puts(str_fact(buf, 5)); puts(str_fact(buf, 50)); } 

Salida

 1 1 120 30414093201713378043612608166064768844377641568960512000000000000 

No irá con los tipos C estándar, necesita algo más (tal vez una cadena). Por favor, visite http://onlinemschool.com/math/formula/factorial_table/

Como puedes ver, es un número bastante grande.

 /* program to calculate large factorials with exact precision original program by chux, modified by ringzero */ #include  #include  char *strfact_mult(char *s, unsigned x) { // modified code starts int len = strlen (s); int carry = 0; for ( int i = 1; i <= len; ++i ) { int product = (s[len - i] - '0') * x + carry; s[len - i] = product % 10 + '0'; carry = 0; if ( product > 9 ) { carry = product / 10; if ( i == len ) { ++len; memmove (&s[1], s, len); s[0] = '0'; } } } // modified code ends //unsigned sum = 0; //size_t len = strlen(s); //size_t i = len; //while (i > 0) { // sum += (s[--i] - '0')*x; // s[i] = sum%10 + '0'; // sum /= 10; //} //while (sum) { // len++; // memmove(&s[1], s, len); // s[i] = sum%10 + '0'; // sum /= 10; //} return s; } char *str_fact(char *dest, unsigned n) { strcpy(dest, "1"); while (n > 1) { strfact_mult(dest, n--); } return dest; } int main (void) { char buf[1000]; puts(str_fact(buf, 0)); puts(str_fact(buf, 1)); puts(str_fact(buf, 5)); puts(str_fact(buf, 50)); }