THE PUZZLET PAGE

 FUNCTION:  Factorial().  This useful function takes an integer as its argument and returns the factorial of that integer.  For example, if the argument is 4, the function returns 24 (because 4! = 1 x 2 x 3 x 4 = 24). This code will only find factorials up to a maximum possible value of an int64 integer.  You can change this in the declarations to a uint64 if you want, but both introduce an error above Factorial 2. Certain other Basic dialects, such as UBasic and Liberty Basic, can work with much larger integers.  See the table below for the limits.

 Type Exponent of 2 Value int 230 1073741824 uint 231 2147483648 int64 261 2305843009213693952 uint64 262 4611686018427387904

 Declaring the function must be done like this: declare Factorial(f: int). Here's the code itself: sub Factorial(f) ' Returns the factorial of f. ' Only correct up to f = 20! ' By Dave Ellis. def it: int def fact: int64 if f > 20     fact = 0 else     fact = 1    for it = 1 to f         fact = fact*it    next it endif return fact

 Overview:  The output will be stored in variable fact, which is initialised to unity.  A simple FOR-NEXT loop uses variable it to iterate over the range from 1 to the argument. At each iteration, fact is multiplied by it and the result saved into fact, over-writing the last value. This continues until all values up to and including the argument have been used in it. fact now holds the factorial of the argument, and this is returned to the calling routine. The following few lines of code do all the work.  I've numbered them to make explanations simpler.

 1 2 3 4 5 6 8 9 10 11 12 def it: int def fact: int64 if f > 20     fact = 0 else     fact = 1     for it = 1 to f         fact = fact*it     next it endif return fact

 Let's look at the above code in detail now.

 1 def it: int.  Variable it is created, to be used as the iterator in the FOR-NEXT loop below.

 2 def fact: int64.  Creates variable fact.  This will be used to hold the factorial as it is built up.  Note that it's a long integer to enable the factorial to be as large as possible, since factorials very quickly become extremely large.

 3 if f > 20.  Line 3 is included specifically to prevent errors.  IBasic's limits for maximum integer length will be reached above factorial 20, and will result in an error.  This can be avoided by only processing arguments of 20 or less.  The question is posed here: "Is the variable stored in argument f greater than 20?" You will see in the lines below how this is used to jump out of the function and return a zero, indicating error.

 4 fact = 0.   Line 4 is only executed if the answer to the question in line 3 is in the affirmative.  It means that the function's argument is greater than 20, which would cause an error.  It's handled by assigning value 0 to variable fact, which will be returned to the calling routine.

 5 else.  Indicates that there is an alternative action in the event the question in line 3 was "No."  The code would in that case jump from line 3 to line 6.

 6 fact = 1.  fact, which will eventually hold the argument's factorial, is initialised to unity.  It cannot be zero, since, in subsequent multiplications the result would always be zero, and it can't be greater than 1 or all subsequent multiplications would be incorrect.

 7 for it = 1 to f.  The main FOR-NEXT loop is opened.  Variable it is the iterator, going from 1 to f in value.  f is the argument itself.  This short loop is where the real work of the function is carried out!

 8 fact = fact*it.  This line is saying "Multiply the value stored in variable fact by the current value of iterator it and store the result in fact, over-writing the value that was previously stored there."  This just duplicates the pen-and-paper process of finding a factorial - try it and see for yourself . . .

 9 next it.  Housekeeping - completes the FOR-NEXT clause.

 10 return fact. Once the code reaches this line, the FOR-NEXT loop has iterated the correct number of times and fact's value will be equal to the argument's factorial.  All that remains is to return the value in fact  to the calling routine. Note that line 10 can be reached direct from the error condition (when one exists) in line 4, in which case variable fact would be holding value 0 for return to the calling routine.

As you can see, there's very little to the code, and the explanation given above may still not be clear enough. The inset table traces through the action when 6! (factorial 6) is required, and that shows very well how the code is working.

 it fact (start) fact (end) 1 2 3 4 5 6 1 1 2 6 24 120 1 2 6 24 120 720

 Note that an earlier version of this function did not trap the error arising if its argument was too large.  This version handles that seamlessly, by which I mean that your old code will run perfectly well with either.

 MAIN MENU HOW DOES IT WORK?

 Site design/maintenance: Dave Ellis E-mail me! Last Updated: February 4th, 2010.