COMPUTING FACTORIALS

Computing the factorial of a non-negative integer is of course one of the stock examples of recursive definition, and Scheme predictably expresses it concisely:

(define factorial
  (lambda (n)
    (if (zero? n)
        1
        (* n (factorial (- n 1))))))
For somewhat greater efficiency, one can make the procedure tail-recursive:

(define factorial
  (lambda (n)
    (let loop ((counter 1)
               (so-far 1))
      (if (> counter n)
          so-far
          (loop (+ counter 1) (* counter so-far))))))
Note that in both these versions small numbers are multiplied in before large ones, so that the intermediate results remain small, or at least not humungous, for as long as possible. In Pascal, this would make no difference, since all integer multiplications are equally fast. Scheme's integers, however, are not bounded by maxint, so that large factorials can be computed exactly with either version of the procedure. For such operands, multiplying m by n becomes an O(log m log n) operation.


This document is available on the World Wide Web as

http://www.math.grin.edu/~stone/events/scheme-workshop/factorials.html


created July 9, 1995
last revised June 21, 1996

John David Stone (stone@math.grin.edu)