![]() |
Previous | Table Of Contents | Next | ![]() |
Factorials
Let's now write a program which can compute the factorial of any positive integer n. The value of n factorial (usually written as n!) is defined as:
n! = n * (n-1) * (n-2) * ... * 3 * 2 * 1
Many calculators have factorial keys but our RPN calculator does not. That is not a problem since we can just write a program to compute a factorial. Clearly this program is going to need to allow the operator to specify the desired factorial at run-time, and hence it will need to accept a passed parameter from the operator. So we will write a program that computes the factorial of whatever positive integer is placed into the X stack location before the program is initiated.
We will base our program upon a loop which we iterate through n times. We will employ the DSZ statement to control this loop and hence we must employ register 0 to hold an integer which counts from n to 0. As we discussed in the last section, even though there are n+1 integers between n and 0, the body of the loop will only be executed n times, which is just what we want.
Before entering the loop we will initialize a particular data memory location
with the value 1. Then during the first iteration of the loop we will
multiply the contents of this data memory location by n, thereby computing
the value 1 * n. During the next iteration of the loop we will multiply
the contents of this data memory location by n-1, thereby computing the value
You can find the factorial program in the Factorial.txt file and it is reprinted below:
At the beginning of this program are some statements that are designed to protect the program from bad data. The factorial operation is only defined for positive integers. What should the program do if it finds a non-integer or negative value in the X stack location? Most computer programs are able to generate messages to the operator to alert him to errors such as these, but RPN calculator programs can only generate numbers. Therefore this program employs the INT statement to toss any fractional portion of the value found in the X stack location. And if this value is negative the program branches to a special label (LBL 2) which displays the "result" as 1. Hopefully the operator will catch on when he sees the result of all negative factorials being reported as 1. This code is an example of defensive programming and is an excellent idea. All of us have seen programs crash when they encountered something their designer had not protected against.
To decide if the passed parameter is negative the program employs the x<0 instruction. This is an example of one of the eight conditional statements available on the calculator. The other conditional statements are x>0, x=0, x!=0, x<=y, x>y, x!=y, and x=y. All these conditional statements work similar to each other in that if the condition is false then the program skips the next instruction in program memory. So if the statement x<0 is false, then the GTO 2 statement will be skipped. But if x is either less than or equal to zero then the program will branch to LBL 2 where it attempts to alert the operator to the problem.
After the defensive code that checks the legality of the n parameter passed to the program in the X stack location, the program next checks if n = 0. If so the program jumps to LBL 2 to display the result as 1 (which is the correct answer).
Next in the program appear 2 initialization steps. We initialize register 0 with the passed parameter n. We must employ register 0 for this purpose since the DSZ statement is linked with register 0. And we initialize register 1 with the value 1. During each iteration of the loop we will multiply the value in register 1 by a new factor such as (n-1) or (n-2) etc. So we must initialize register 1 to unity before we enter the loop.
With these preliminaries out of the way we can
finally enter the program loop. This is the code between the
LBL 1 statement and the GTO 1 statement that immediately follows (and hence
is linked to) the DSZ statement. The only new statement in this section is
an example of the generic STO* n instruction which replaces the contents
of register n with the prior value in register n multiplied by the contents
of the X stack location. This is the statement that, during each iteration
of the loop, tacks on another factor in the ever expanding string of factors
Note that this program has two RTN statements, which means it can halt in two different places. This is not unusual in programs, and is illustrated in the following flow chart for the program:
Remember that this program requires a passed parameter and hence to employ this program to compute, say 5!, you must initiate it via a keystroke sequence such as 5, GSB 0. Single step through the program and watch how 5! gets built in register 1. During the program initialization you will see register 1 getting populated with the value 1. Then during the first iteration of the program loop the value in register 1 will be multiplied by 5 (this value having been taken from register 0). During the next iteration of the loop the value in register 1 will be multiplied by 4 (this value having been taken from register 0). Eventually register 1 will hold 1 * 5 * 4 * 3 * 2 * 1 = 120 = 5!
You can use the program to discover that 69! = 1.71e+98 which is the number 1.71 multiplied by 1098. This means this number has 99 columns in it and hence is huge. But if you next calculate the factorial of 70 or any number larger than 70 the answer will always come back as 9.999999999e+99. In these cases the program is actually failing. It turns out that 9.999999999e+99 is the largest number that the calculator can handle. All calculators, and computers for that matter, have a maximum and minimum number that they can deal with.
![]() |
Previous | Table Of Contents | Next | ![]() |