Klook.com Some Thoughts on Random Number Generation

Suppose we wanted to select a number at random, say, from an interval of 1 to 27 inclusive. How could we go about it in a computer program?

For some languages it’s surprisingly easy; tools for random number selection exist in these languages. If we wanted to “pick a card” from 1 to 27 in BASIC, or rather the DOS-based variant QBASIC, we would use

RANDOMIZE TIMER

LET NRANDOM = INT(RND * 27) + 1

Since QBASIC is a loose, weakly-typed language, NRANDOM is defined “on the fly” and its type determined by what is assigned to it.

To do the same in C++ we’d write

srand((unsigned)time(NULL));

int nrandom = rand() % 27;

In both cases only two lines are needed: one to appropriate the system clock, and one to apply a random number function with the constraints of the language and our chosen limit of 27.

When we need a random number generated by the computer, we have to include a random or quasi-random input parameter; customarily, programmers use the computer’s clock.

Java is syntactically similar to C/C++, so we’d expect it to have a very similar way of handling random numbers. However, Java has an object class called Random, which is accessed by

import java.util.Random;

Cay Horstmann says that to get random numbers we’d construct an object of the Random class, then use one of these methods:nextInt(n), which returns a random integer between 0 (inclusive) and n (exclusive), andnextDouble(), which returns a random floating point number between 0 (inclusive) and 1 (exclusive).Horstmann gives an example with the cast of a die:

Random generator = new Random();

int d = 1 + generator.nextInt(6);

generator.nextInt(6) yields a random number between 0 and 5 inclusive, which we’d correct by adding 1 to get the interval 1 to 6. If we wanted to get a number between 1 and 27, we’d substitute 27 for 6 in nextInt().

Random number functions are available in parametric languages such as SPSS (Statistical Package for the Social Sciences) and SAS (Statistical Analysis System). Usually statistics such as Mean and Standard Deviation are invoked using number parameters or other brief commands. In SPSS code written directly, the only randomizer of which I’m aware is the SAMPLE command, followed by a number which, if memory serves me correctly, is the number of samples to be extracted at random from a list of data records. In that case, the only way we could get a random number between 1 and 27 is to have a file of 27 records each containing only a unique number between 1 and 27 inclusive, and using the SAMPLE command followed by 1. Nowadays, social scientists favor SPSS for Windows, which puts SPSS code “under the hood.” As it’s a proprietary language with an aggressively-enforced licensing system, I’m afraid to illustrate the graphic user interface from the package, so we’ll have to use our imagination for this: a viewer window is invoked along with a Data Editor window that asks for a data source. The viewer window gives program system responses, the Data Editor window lets us choose our analysis. It’s possible to enter data in a spreadsheet frame on the Data Editor, and for our purposes it’s necessary to create a list of numbers 1.0 to 27.0. From the Data Editor’s pulldown menu we can select

Transform->Random Number Seed

— that gives the option of manually choosing a seed value, or allowing the computer to choose it at random.

Transform->Compute

calls a dialog with a spinner box from which we can choose a function from a long list. For random number selection we’d select

UNIFORM(max)

where max can be set to 27, the higher limit of an interval starting at 0 (there’s a function named RND, but its name is misleading; it stands for “Round,” not “Random.”). If the package has been properly licensed, the “OK” button won’t be disabled and we may get our random number.

But what can we do when the language we use doesn’t have built-in randomize functions? For a programmer who’s an astute mathematician it might be a minor inconvenience but not a major roadblock. For others there are algorithms available in some reference materials. Michel Boillot wrote a Fortran textbook containing a linear congruential algorithm that can be used to write random number generators. In the linear congruential method, a pseudo-random number is generated using an input “seed” value (everywhere I look, it seems, authors use the word “seed”). The basic formula is

XN + 1 = (A XN + C) MOD M

The value X, as a result of the computations, is always a real number between 0 and 1.

I wrote a Fortran subroutine that uses the linear congruential algorithm:

SUBROUTINE IRNDSB(IFIRST,ILAST,IRNDM,ISEED)

DATA IA,IM,IC/13077,32768,6925/

ISEED=MOD((ISEED*IA+IC),IM)

X=FLOAT(ISEED)/FLOAT(IM)

IRNDM=X*(ILAST-IFIRST+1)+IFIRST

RETURN

END

IFIRST and ILAST represent the endpoints of the interval from which the routine will select the number at random; these variables make the routine general enough to accept any endpoints, not just 1 and 27. IRNDM is the random number returned by the routine. ISEED is the input used. In Fortran every integer variable is prefixed by “I.” The numeric constants 13077, 32768, and 6925 were not clearly explained by Boillot to my recollection, but I recognize them as powers of two, minus one.

I’d also written a COBOL version, and not to disparage COBOL (much of my field experience is in it), but that language was not created for brevity, and the COBOL version is rather wordy.

In later editions of his textbook Boillot wrote his own Fortran function RAND(), which returns real random numbers between 0 and 1. The calling program uses it to yield an integer between 1 and 6, as below:

NUMBR = RAND(1)*6.0 + 1.0

FUNCTION RAND(K)

INTEGER IM, IB, IA

DATA IM, IB, IA/ 24211, 32767, 19727/

IA = MOD(IM*IA, IB)

RAND = FLOAT(IA)/FLOAT(IB)

RETURN

END

Again substitute 27.0 for 6.0 and we have yet another way of getting the random number we wanted.

This may all be a trivial exercise for some gifted programmers, but it’s a nice find for many who need it.

1. Horstmann, Cay, Big Java (2002, John Wiley & Sons, Inc., pp. 262-263)

2. Boillot, Michel, Understanding Fortran (1978, West Publishing Company, St. Paul, pp.372-375)

3. Boillot, Michel, Understanding Fortran77 with Structured Problem Solving (1984, 1987, West Publishing Company, St. Paul, New York, Los Angeles, San Francisco, p. 239)