As it is written, calling factorial( -1 )
would grow the activation chain without limit.
public int factorial( int N )
{
if ( N == 0 )
return 1;
else
return N * factorial( N-1 ) ;
}
The first activation factorial( -1 )would activate factorial( -2 ),
which would activate factorial( -3 ), which would activate factorial( -4 ), and so on.
The base case (of N == 0) would never be reached.
Eventually the computer system would run out of resources,
and the program would stop running.
Defensive programming is when a programmer anticipates
problems and writes code to deal with them.
To avoid the disaster a negative parameter would cause,
sometimes factorial() is written like this:
public int factorial( int N )
{
if ( N <= 0 )
return 1;
else
return N * factorial( N-1 ) ;
}
But, according to the math-like definition, this is not correct.
The value of factorial( -1 ) is undefined,
not equal to one.
Potentially, returning an incorrect value and continuing on as if nothing is
wrong might cause a greater disaster than stopping the computer system.
Sometimes the method is written to throw an exception when an illegal argument is detected. (Exceptions are discussed in a future chapter.) But this adds complication since now the caller must deal with a possible exception.
Perhaps the best idea is to write factorial()
so that it follows the math-like definition exactly.
Make it the responsibility of the caller to
make sure that the argument is within range.
Here is another idea: why not have factorial() use
the absolute value of its argument to be sure that it is positive?