Le programme ne renvoie pas de sortie pour une valeur d’entrée élevée telle que 50. Il renvoie 0. Il s’agit d’un programme factoriel utilisant la récursivité.

/*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! est un très grand nombre (plus de 60 chiffres) et 2^64 est inférieur à 50! . La raison pour laquelle vous n’obtenez pas le bon nombre est que vous obtenez un débordement , vous comptez au-dessus de la limite de ce que votre ordinateur peut calculer.

 enter n 50 -3258495067890909184 

Si vous avez un entier de 64 bits, la plus grande valeur qu’il puisse représenter est 2 ^ 64, ce qui est inférieur à 50 !. Par conséquent vous obtenez débordement.

Normalement, dans ces situations, vous recourez à une astuce similaire à un système 4 bits exécutant du code 8 bits en doublant le nombre d’instructions par mot (comme Intels le premier processeur avait un code 8 bits).

Pour que votre système 64 bits puisse réellement gérer les mots de 128 bits, il vous suffit d’écrire un algorithme qui place les données en “morceaux” afin de pouvoir doubler la longueur de votre mot.

50! est 30414093201713378043612608166064768844377641568960512000000000000 ou environ 3.04e+64 , un nombre de 215 bits. Cette valeur dépasse généralement la plage de types tels que long . Même uintmax_t et unsigned long long n’ont besoin que de pouvoir représenter au moins des entiers 64 bits.

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

Pour obtenir une réponse exacte, le code pourrait utiliser d’autres types. Ce qui suit utilise une représentation sous forme de chaîne / décimale d’un entier. Cela fonctionne pour les grandes valeurs de n , la fonctionnalité correcte étant limitée par la taille de la mémoire tampon.

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

Sortie

 1 1 120 30414093201713378043612608166064768844377641568960512000000000000 

Cela n’ira pas avec les types C standard, vous avez besoin de quelque chose d’autre (peut-être une chaîne). Veuillez consulter http://onlinemschool.com/math/formula/factorial_table/

Comme vous pouvez le constater, le nombre est assez élevé.

 /* 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)); }