Calculating Factorials

A factorial, denoted as, for example, 5!, is the product of all numbers up to and including the number in question, so: 5! = 5 x 4 x 3 x 2 x 1 = 120.

We might use iteration to calculate factorials:

factorial:=1;
for i:= 1 to n do
 factorial : = factorial * i;

Thus: 1 x 1 = 1; 1 x 2 = 2; 2 x 3 = 6; 6 x 4 = 24; 24 x 5 = 120.

It is also possible to use recursion to calculate factorials:

function factorial (n:integer) : integer;
begin
  if n=0 then
    factorial := 1
  else
    factorial := n * factorial (n-1);
end;

begin
  n:=strtoint(edit1.text);
  result := factorial (n);
  showmessage('Answer is ' + result); 
end.

The factorial function takes n (integer) as a parameter, for example 5. The value of the parameter is compared with zero, in which case the function returns 1. 5 is not zero so the else part is executed, that is the result of the current call of factorial is set to the current value of n times the result of a second call of the function. The second call of the function passes n-1 (4) as its parameter so what we are effectively doing here is producing 5 * 4.

Calls to the factorial function will be made as follows:

factorial (5) gives factorial := 5 * factorial (4) 
factorial (4) gives factorial := 4 * factorial (3)
factorial (3) gives factorial := 3 * factorial (2)
factorial (2) gives factorial := 2 * factorial (1)
factorial (1) gives factorial := 1 * factorial (0)
factorial (0) finishes the calls

The calls unwind in reverse order performing the multiplications as they go:

The result from factorial (0) is multiplied by the result from factorial 1 (1 * 1 = 1)
Then the result from factorial (1) is multiplied by the result from factorial (2)  (1 * 2 = 2)
Then the result from factorial (2) is multiplied by the result from factorial (3)  (2 * 3 = 6)
Then the result from factorial (3) is multiplied by the result from factorial (4)  (6 * 4 = 24)
Then the result from factorial (4) is multiplied by the result from factorial (5)  (24 * 5 = 120)

Note that beyond 16! results are unreliable: 17! returns a negative number: why? These errors can be avoided by using int64, but this only moves the goal posts, errors will eventually emerge.

Back