Reputation: 65
I don't understand why my code is still printing int values (that are overflown) while I want unsigned long values!
There is my code :
#include <stdio.h>
unsigned long factorial(int num) {
if ((num == 0) || (num == 1 )) {
return 1;
} else if (num < 0) {
return 0;
} else {
return num * factorial(num - 1);
}
}
int main(void) {
int num;
char liste;
printf("Choisir un nombre pour trouver son factoriel : ");
//Translation : "Choose a number to find its factorial" 🥖
scanf("%d", &num);
printf("factoriel de %d : %lu\n", num, factorial(num));
}
It is a very basic code to return factorial value but I'm just a beginner.
Upvotes: 0
Views: 347
Reputation: 48053
The factorial function grows very fast. Just about no matter what type you use for your computations, it's going to overflow pretty soon.
On a machine where type unsigned long
has 32 bits (which is all that's guaranteed), your program can correctly compute 12! = 479001600 (but nothing larger). I suspect that's what you're seeing.
On a machine where type unsigned long
has 64 bits, your program can correctly compute 20! = 2432902008176640000. (My machine has 64-bit longs, and I used your program to compute this result, and it worked fine.)
So your program is actually fine; I can't see anything wrong with it. (Well, there's an unused variable liste
, and a stray loaf of bread in a comment. :-) )
If your compiler and C library both support type long long
, you can try this to increase the range on your machine:
#include <stdio.h>
unsigned long long factorial(int num) {
if (num < 0) {
return 0;
} else if (num <= 1 ) {
return num;
} else {
return num * factorial(num - 1);
}
}
int main(void) {
int num;
printf("Choisir un nombre pour trouver son factoriel : ");
scanf("%d", &num);
printf("factoriel de %d : %llu\n", num, factorial(num));
}
But, again, this'll only get you up to 20!. (In this version I have also cleaned up the logic of your factorial
function slightly.)
If %llu
doesn't work, you can try %Lu
.
Some compilers support a 128-bit type (I think gcc calls it _uint128_t
or something like that), and this could theoretically get you up to 34! = 295232799039604140847618609643520000000.
But beyond that you'd have to use a "multiple precision" or "arbitrary precision" library such as GMP. For example, 100! has 525 bits, and 1000! has 8530 bits.
Upvotes: 1