Factorial n is the product n! = n * (n-1) * (n-2) * ... * 2 * 1
Examples: 1! = 1; 2! = 2; 3! = 6; 6! = 720; 100! ~= 9.333e157.
In a simple language like BASIC you'd write:
10 INPUT N
20 T=N
30 IF N<3 THEN 70
40 N=N-1
50 T=T*N
60 GOTO 30
70 PRINT T
which works for any positive integer, and omits any unnecessary final multiplication by 1.
You can't do anything so simple on the Sinclair, as it has only one memory register. You can juggle N and T using one memory and the memory exchange function so that one is kept in the working registers while the other is kept in memory, as follows:
step # | symbol | function | x | y | m | notes |
---|---|---|---|---|---|---|
00 | 2 | sto | n | t=n | ||
01 | F | - | n | n | t | |
02 | 3 | # | n | n | t | |
03 | 3 | 3 | 3 | n | t | |
04 | - | = | n-3 | t | ||
05 | A | shift | n-3 | t | ||
06 | 1 | go if neg | n-3 | t | end if n<3 | |
07 | 2 | 2 | ||||
08 | 2 | 2 | ||||
09 | E | + | n-3 | n-3 | t | |
10 | 3 | # | n-3 | n-3 | t | |
11 | 2 | 2 | 2 | n-3 | t | |
12 | . | * | n-1 | n-1 | t | |
13 | A | shift | n-1 | n-1 | t | |
14 | 5 | MEx | t | n-1 | n-1 | save n in mem while working on accumulator |
15 | - | = | t(n-1) | n-1 | ||
16 | A | shift | t(n-1) | n-1 | ||
17 | 5 | MEx | n-1 | t(n-1) | save accumulator and get n back | |
18 | A | shift | n-1 | t(n-1) | ||
19 | 2 | goto | n-1 | t(n-1) | ||
20 | 0 | 0 | ||||
21 | 1 | 1 | ||||
22 | 5 | rcl | t | t | ||
23 | 0 | stop | t | t | ||
24 | A | shift | t | t | ||
25 | 2 | goto | t | t | ||
26 | 0 | 0 | ||||
27 | 0 | 0 |
This is 28 steps of 4 bits each, or 14 bytes.
Just for comparison, here is a factorial program for the Hewlett Packard HP25, a calculator of about the same period (a couple of years earlier) but much more expensive and actually useable. The HP25 had 49 steps each holding a whole step, including any shifts; each being 8 bits. It uses RPN, with a 4-level stack, plus it had 8 memories each capable of arithmetic operations.
step # | display | function | x | y | z | t | R0 | notes |
---|---|---|---|---|---|---|---|---|
01 | 23 00 | STO 0 | n | t=n | ||||
02 | 02 | 2 | 2 | n | t | |||
03 | 14 51 | x>=y | 2 | n | t | end if n <= 2 | ||
04 | 13 10 | GTO 10 | 2 | n | t | |||
05 | 34 | CLR x | 0 | n | t | |||
06 | 01 | 1 | 1 | n | t | |||
07 | 41 | - | n- | t | ||||
08 | 23 61 00 | STO * 0 | n-1 | t(n-1) | this op does R0=R0*x without disturbing stack | |||
09 | 13 02 | GTO 02 | n-1 | t(n-1) | ||||
10 | 24 00 | RCL 0 | t | t |
This is only 10 bytes.