Velocity Reviews > The wrong with factorial function

# The wrong with factorial function

Blue sky
Guest
Posts: n/a

 11-02-2008
Hi,I am a new C++ learner.The follow prgram produces a wrong
result,but I can't find the wrong.Can you help me?Thank you!

#include<stdio.h>

long factorial( long number);

int main()
{
int a;

for ( a = 0;a<10;a++ ){
printf("%2d! = %1d\n",a,factorial( a ));
}

return 0;
}

long factorial( long number )
{
if ( number <=1 ){
return 1;
}
else{
return ( number * factorial(number - 1));
}

the result as follows
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! =5040
8! = -25216
9! = -30336
Atentions,please.The result 8! and 9! are wrong.But Why?

Martin Ambuhl
Guest
Posts: n/a

 11-02-2008
Blue sky wrote:
> Hi,I am a new C++ learner.The follow prgram produces a wrong
> result,but I can't find the wrong.Can you help me?Thank you!

[...]
> Atentions,please.The result 8! and 9! are wrong.But Why?

Luckily, none of your code involves C++ rather than C. If it had,
then questions about it would not be topical here, since C++ is a
different language.

Note what happens with the following code on your machine and think
about what that might mean. You might also try the same code with
'signed' instead of 'unsigned' and SHRT_MAX, LONG_MAX, and LLONG_MAX
instead of USHRT_MAX, ULONG_MAX, and ULLONG_MAX. Notice what happens then.

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned int i, usok = 1, ulok = 1, ullok = 1;
unsigned short usfact = 1;
unsigned long ulfact = 1;
unsigned long long ullfact = 1;
printf("[Output]\n"
"The limiting values are implementation-specific.\n\n");
for (i = 1; ullok; i++) {
if (usok) {
if (USHRT_MAX / i < usfact) {
printf("%u! will overflow an unsigned short.\n"
"An unsigned short is at most %u.\n", i,
USHRT_MAX);
usok = 0;
}
else {
usfact *= i;
ulfact *= i;
ullfact *= i;
printf("%u! is %u (unsigned short)\n", i, usfact);
}
}
if (!usok && ulok) {
if (ULONG_MAX / i < ulfact) {
printf("%u! will overflow an unsigned long.\n"
"An unsigned long is at most %lu.\n", i,
ULONG_MAX);
ulok = 0;
}
else {
ulfact *= i;
ullfact *= i;
printf("%u! is %lu (unsigned long)\n", i, ulfact);
}
}
if (!ulok) {
if (ULLONG_MAX / i < ullfact) {
printf("%u! will overflow an unsigned long long.\n"
"An unsigned long long is at most %llu.\n", i,
ULLONG_MAX);
ullok = 0;
}
else {
ullfact *= i;
printf("%u! is %llu (unsigned long long)\n", i,
ullfact);
}
}

}
return 0;
}

[Output]
The limiting values are implementation-specific.

1! is 1 (unsigned short)
2! is 2 (unsigned short)
3! is 6 (unsigned short)
4! is 24 (unsigned short)
5! is 120 (unsigned short)
6! is 720 (unsigned short)
7! is 5040 (unsigned short)
8! is 40320 (unsigned short)
9! will overflow an unsigned short.
An unsigned short is at most 65535.
9! is 362880 (unsigned long)
10! is 3628800 (unsigned long)
11! is 39916800 (unsigned long)
12! is 479001600 (unsigned long)
13! will overflow an unsigned long.
An unsigned long is at most 4294967295.
13! is 6227020800 (unsigned long long)
14! is 87178291200 (unsigned long long)
15! is 1307674368000 (unsigned long long)
16! is 20922789888000 (unsigned long long)
17! is 355687428096000 (unsigned long long)
18! is 6402373705728000 (unsigned long long)
19! is 121645100408832000 (unsigned long long)
20! is 2432902008176640000 (unsigned long long)
21! will overflow an unsigned long long.
An unsigned long long is at most 18446744073709551615.