7.1 Uniform Deviates 275 As for references on this subject,the one to turn to first is Knuth [1].Then try [2].Only a few of the standard books on numerical methods [3-4]treat topics relating to random numbers. CITED REFERENCES AND FURTHER READING: Knuth,D.E.1981,Seminumerical Algorithms,2nd ed..vol.2 of The Art of Computer Programming (Reading.MA:Addison-Wesley),Chapter 3,especially $3.5.[1] Bratley.P..Fox.B.L..and Schrage,E.L.1983.A Guide to Simulation (New York:Springer- Verlag).[2] Dahlquist,G.,and Bjorck,A.1974,Numerica/Methods (Englewood Cliffs,NJ:Prentice-Hall). Chapter 11.[3] Forsythe,G.E.,Malcolm,M.A.,and Moler,C.B.1977,Computer Methods for Mathematical Computations(Englewood Cliffs,NJ:Prentice-Hall),Chapter 10.[4] 7.1 Uniform Deviates Uniform deviates are just random numbers that lie within a specified range (typically 0 to 1),with any one number in the range just as likely as any other.They are,in other words,what you probably think "random numbers"are.However, we want to distinguish uniform deviates from other sorts of random numbers,for example numbers drawn from a normal(Gaussian)distribution of specified mean and standard deviation.These other sorts of deviates are almost always generated by performing appropriate operations on one or more uniform deviates,as we will see Programs in subsequent sections.So,a reliable source of random uniform deviates,the subject of this section,is an essential building block for any sort of stochastic modeling or OF SCIENTIFIC Monte Carlo computer work. 61 System-Supplied Random Number Generators Most C implementations have,lurking within,a pair of library routines for initializing,and then generating,"random numbers."In ANSI C,the synopsis is: #include <stdlib.h> #define RAND_MAX... void srand(unsigned seed); Numerical Recipes 10621 43106 int rand(void); You initialize the random number generator by invoking srand(seed)with (outside some arbitrary seed.Each initializing value will typically result in a different North Software. random sequence,or a least a different starting point in some one enormously long sequence.The same initializing value of seed will always return the same random sequence,however. You obtain successive random numbers in the sequence by successive calls to rand().That function returns an integer that is typically in the range 0 to the largest representable positive value of type int (inclusive).Usually,as in ANSIC, this largest value is available as RAND_MAX,but sometimes you have to figure it out for yourself.If you want a random float value between 0.0 (inclusive)and 1.0 (exclusive),you get it by an expression like
7.1 Uniform Deviates 275 Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copyin Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software. Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5) g of machinereadable files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America). As for references on this subject, the one to turn to first is Knuth [1]. Then try [2]. Only a few of the standard books on numerical methods [3-4] treat topics relating to random numbers. CITED REFERENCES AND FURTHER READING: Knuth, D.E. 1981, Seminumerical Algorithms, 2nd ed., vol. 2 of The Art of Computer Programming (Reading, MA: Addison-Wesley), Chapter 3, especially §3.5. [1] Bratley, P., Fox, B.L., and Schrage, E.L. 1983, A Guide to Simulation (New York: SpringerVerlag). [2] Dahlquist, G., and Bjorck, A. 1974, Numerical Methods (Englewood Cliffs, NJ: Prentice-Hall), Chapter 11. [3] Forsythe, G.E., Malcolm, M.A., and Moler, C.B. 1977, Computer Methods for Mathematical Computations (Englewood Cliffs, NJ: Prentice-Hall), Chapter 10. [4] 7.1 Uniform Deviates Uniform deviates are just random numbers that lie within a specified range (typically 0 to 1), with any one number in the range just as likely as any other. They are, in other words, what you probably think “random numbers” are. However, we want to distinguish uniform deviates from other sorts of random numbers, for example numbers drawn from a normal (Gaussian) distribution of specified mean and standard deviation. These other sorts of deviates are almost always generated by performing appropriate operations on one or more uniform deviates, as we will see in subsequent sections. So, a reliable source of random uniform deviates, the subject of this section, is an essential building block for any sort of stochastic modeling or Monte Carlo computer work. System-Supplied Random Number Generators Most C implementations have, lurking within, a pair of library routines for initializing, and then generating, “random numbers.” In ANSI C, the synopsis is: #include <stdlib.h> #define RAND_MAX ... void srand(unsigned seed); int rand(void); You initialize the random number generator by invoking srand(seed) with some arbitrary seed. Each initializing value will typically result in a different random sequence, or a least a different starting point in some one enormously long sequence. The same initializing value of seed will always return the same random sequence, however. You obtain successive random numbers in the sequence by successive calls to rand(). That function returns an integer that is typically in the range 0 to the largest representable positive value of type int (inclusive). Usually, as in ANSI C, this largest value is available as RAND_MAX, but sometimes you have to figure it out for yourself. If you want a random float value between 0.0 (inclusive) and 1.0 (exclusive), you get it by an expression like
276 Chapter 7.Random Numbers x rand()/(RAND_MAX+1.0); Now our first,and perhaps most important,lesson in this chapter is:be very. very suspicious of a system-supplied rand()that resembles the one just described. If all scientific papers whose results are in doubt because of bad rand()s were to disappear from library shelves,there would be a gap on each shelf about as big as your fist.System-supplied rand()s are almost always linear congruential generators,which generate a sequence of integers I1,I2,13,...,each between 0 and m -1 (e.g.,RAND_MAX)by the recurrence relation 1j+1=ali+c (mod m) (7.1.1) Here m is called the modulus,and a and c are positive integers called the multiplier and the increment respectively.The recurrence (7.1.1)will eventually repeat itself. with a period that is obviously no greater than m.Ifm,a,and c are properly chosen, then the period will be of maximal length,i.e.,of length m.In that case,all possible g integers between 0 and m-1 occur at some point,so any initial"seed"choice of Io is as good as any other:the sequence just takes off from that point. Although this general framework is powerful enough to provide quite decent random numbers,its implementation in many,if not most,ANSI C libraries is quite flawed;quite a number of implementations are in the category "totally botched." Blame should be apportioned about equally between the ANSI C committee and the implementors.The typical problems are these:First,since the ANSI standard specifies that rand()return a value of type int-which is only a two-byte quantity on many machines-RAND_MAX is often not very large.The ANSI C standard requires only that it be at least 32767.This can be disastrous in many circumstances: for a Monte Carlo integration(87.6 and $7.8),you might well want to evaluate 106 N兰 to dir different points,but actually be evaluating the same 32767 points 30 times each,not at all the same thing!You should categorically reject any library random number routine with a two-byte returned value. Second,the ANSI committee's published rationale includes the following mischievous passage:"The committee decided that an implementation should be allowed to provide a rand function which generates the best random sequence 10621 possible in that implementation,and therefore mandated no standard algorithm.It Numerical Recipes 43106 recognized the value,however,of being able to generate the same pseudo-random sequence in different implementations,and so it has published an example.... [emphasis added'The“example'”is (outside Software. unsigned long next=1; North int rand(void)/*NOT RECOMMENDED (see text)*/ next=next*1103515245+12345; return (unsigned int)(next/65536)%32768; void srand(unsigned int seed) next=seed;
276 Chapter 7. Random Numbers Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copyin Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software. Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5) g of machinereadable files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America). x = rand()/(RAND_MAX+1.0); Now our first, and perhaps most important, lesson in this chapter is: be very, very suspicious of a system-supplied rand() that resembles the one just described. If all scientific papers whose results are in doubt because of bad rand()s were to disappear from library shelves, there would be a gap on each shelf about as big as your fist. System-supplied rand()s are almost always linear congruential generators, which generate a sequence of integers I1, I2, I3,..., each between 0 and m − 1 (e.g., RAND_MAX) by the recurrence relation Ij+1 = aIj + c (mod m) (7.1.1) Here m is called the modulus, and a and c are positive integers called the multiplier and the increment respectively. The recurrence (7.1.1) will eventually repeat itself, with a period that is obviously no greater than m. If m, a, and c are properly chosen, then the period will be of maximal length, i.e., of length m. In that case, all possible integers between 0 and m − 1 occur at some point, so any initial “seed” choice of I 0 is as good as any other: the sequence just takes off from that point. Although this general framework is powerful enough to provide quite decent random numbers, its implementation in many, if not most, ANSI C libraries is quite flawed; quite a number of implementations are in the category “totally botched.” Blame should be apportioned about equally between the ANSI C committee and the implementors. The typical problems are these: First, since the ANSI standard specifies that rand() return a value of type int — which is only a two-byte quantity on many machines — RAND_MAX is often not very large. The ANSI C standard requires only that it be at least 32767. This can be disastrous in many circumstances: for a Monte Carlo integration (§7.6 and §7.8), you might well want to evaluate 10 6 different points, but actually be evaluating the same 32767 points 30 times each, not at all the same thing! You should categorically reject any library random number routine with a two-byte returned value. Second, the ANSI committee’s published rationale includes the following mischievous passage: “The committee decided that an implementation should be allowed to provide a rand function which generates the best random sequence possible in that implementation, and therefore mandated no standard algorithm. It recognized the value, however, of being able to generate the same pseudo-random sequence in different implementations, and so it has published an example... . [emphasis added]” The “example” is unsigned long next=1; int rand(void) /* NOT RECOMMENDED (see text) */ { next = next*1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } void srand(unsigned int seed) { next=seed; }
7.1 Uniform Deviates 277 This corresponds to equation (7.1.1)with a 1103515245.c 12345,and m =232(since arithmetic done on unsigned long quantities is guaranteed to return the correct low-order bits).These are not particularly good choices for a and c(the period is only 230),though they are not gross embarrassments by themselves. The real botches occur when implementors,taking the committee's statement above as license,try to "improve"on the published example.For example,one popular 32-bit PC-compatible compiler provides a long generator that uses the above congruence,but swaps the high-order and low-order 16 bits of the returned value. Somebody probably thought that this extra flourish added randomness;in fact it ruins the generator.While these kinds of blunders can,of course,be fixed,there remains a fundamental flaw in simple linear congruential generators,which we now discuss. 8g The linear congruential method has the advantage of being very fast,requiring nted for only a few operations per call,hence its almost universal use.It has the disadvantage g that it is not free of sequential correlation on successive calls.Ifk random numbers at a time are used to plot points in k dimensional space (with each coordinate between 0 and 1),then the points will not tend to "fill up"the k-dimensional space,but rather will lie on (k-1)-dimensional "planes."There will be at most about m/k such planes.If the constants m,a,and c are not very carefully chosen,there will be many fewer than that.If m is as bad as 32768,then the number of planes on which triples of points lie in three-dimensional space will be no greater than about the cube root of 32768.or 32.Even if m is close to the machine's largest representable integer, e.g.,~232,the number of planes on which triples of points lie in three-dimensional space is usually no greater than about the cube root of 232,about 1600.You might Programs well be focusing attention on a physical process that occurs in a small fraction of the total volume,so that the discreteness of the planes can be very pronounced. Even worse,you might be using a generator whose choices of m,a,and c have 是 been botched.One infamous such routine,RANDU,with a =65539 and m =231 兰 to dir was widespread on IBM mainframe computers for many years,and widely copied onto other systems [1].One of us recalls producing a "random"plot with only 11 planes,and being told by his computer center's programming consultant that he had misused the random number generator:"We guarantee that each number is 御你A合过 random individually,but we don't guarantee that more than one of them is random." Figure that out Correlation in k-space is not the only weakness oflinear congruential generators. Numerical Recipes -43108. Such generators often have their low-order(least significant)bits much less random than their high-order bits.If you want to generate a random integer between I and (outside 10,you should always do it using high-order bits,as in Software. j=1+(int)(10.0*rand()/(RAND_MAX+1.0)) Ame ying of and never by anything resembling j=1+(rand()%10); (which uses lower-order bits).Similarly you should never try to take apart a "rand()"number into several supposedly random pieces.Instead use separate calls for every piece
7.1 Uniform Deviates 277 Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copyin Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software. Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5) g of machinereadable files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America). This corresponds to equation (7.1.1) with a = 1103515245, c = 12345, and m = 232 (since arithmetic done on unsigned long quantities is guaranteed to return the correct low-order bits). These are not particularly good choices for a and c (the period is only 230), though they are not gross embarrassments by themselves. The real botches occur when implementors, taking the committee’s statement above as license, try to “improve” on the published example. For example, one popular 32-bit PC-compatible compiler provides a long generator that uses the above congruence, but swaps the high-order and low-order 16 bits of the returned value. Somebody probably thought that this extra flourish added randomness; in fact it ruins the generator. While these kinds of blunders can, of course, be fixed, there remains a fundamental flaw in simple linear congruential generators, which we now discuss. The linear congruential method has the advantage of being very fast, requiring only a few operations per call, hence its almost universal use. It has the disadvantage that it is not free of sequential correlation on successive calls. If k random numbers at a time are used to plot points in k dimensional space (with each coordinate between 0 and 1), then the points will not tend to “fill up” the k-dimensional space, but rather will lie on (k − 1)-dimensional “planes.” There will be at most about m1/k such planes. If the constants m, a, and c are not very carefully chosen, there will be many fewer than that. If m is as bad as 32768, then the number of planes on which triples of points lie in three-dimensional space will be no greater than about the cube root of 32768, or 32. Even if m is close to the machine’s largest representable integer, e.g., ∼ 232, the number of planes on which triples of points lie in three-dimensional space is usually no greater than about the cube root of 2 32, about 1600. You might well be focusing attention on a physical process that occurs in a small fraction of the total volume, so that the discreteness of the planes can be very pronounced. Even worse, you might be using a generator whose choices of m, a, and c have been botched. One infamous such routine, RANDU, with a = 65539 and m = 2 31, was widespread on IBM mainframe computers for many years, and widely copied onto other systems [1]. One of us recalls producing a “random” plot with only 11 planes, and being told by his computer center’s programming consultant that he had misused the random number generator: “We guarantee that each number is random individually, but we don’t guarantee that more than one of them is random.” Figure that out. Correlation in k-space is not the only weakness of linear congruential generators. Such generators often have their low-order (least significant) bits much less random than their high-order bits. If you want to generate a random integer between 1 and 10, you should always do it using high-order bits, as in j=1+(int) (10.0*rand()/(RAND_MAX+1.0)); and never by anything resembling j=1+(rand() % 10); (which uses lower-order bits). Similarly you should never try to take apart a “rand()” number into several supposedly random pieces. Instead use separate calls for every piece
278 Chapter 7.Random Numbers Portable Random Number Generators Park and Miller [1]have surveyed a large number of random number generators that have been used over the last 30 years or more.Along with a good theoretical review,they present an anecdotal sampling of a number of inadequate generators that have come into widespread use.The historical record is nothing if not appalling. There is good evidence,both theoretical and empirical,that the simple multi- plicative congruential algorithm Ij+1=alj (mod m) (7.1.2) can be as good as any of the more general linear congruential generators that have c0(equation 7.1.1)-if the multiplier a and modulus m are chosen exquisitely carefully.Park and Miller propose a "Minimal Standard"generator based on the choices RECIPES a=75=16807m=231-1=2147483647 (7.1.3) 9 First proposed by Lewis,Goodman,and Miller in 1969,this generator has in subsequent years passed all new theoretical tests,and(perhaps more importantly) has accumulated a large amount of successful use.Park and Miller do not claim that the generator is"perfect"(we will see below that it is not),but only that it is a good minimal standard against which other generators should be judged. It is not possible to implement equations (7.1.2)and (7.1.3)directly in a high-level language,since the product of a and m-1 exceeds the maximum value IENTIFIC for a 32-bit integer.Assembly language implementation using a 64-bit product 6 register is straightforward,but not portable from machine to machine. A trick due to Schrage [2.3]for multiplying two 32-bit integers modulo a 32-bit constant, without using any intermediates larger than 32 bits (including a sign bit)is therefore extremely interesting:It allows the Minimal Standard generator to be implemented in essentially any programming language on essentially any machine. Schrage's algorithm is based on an approximate factorization of m, Numerica 10.621 43126 m=aq+r,i.e.,q=[m/al,r =m mod a (7.1.4) with square brackets denoting integer part.If r is small,specifically r<q,and 腿 0<z<m-1,it can be shown that both a(z mod g)and r[z/g]lie in the range North 0,...,m-1,and that ∫a(z mod q)-rlz/g ifit is >0. az mod m= a(z mod q)-r[z/g]m otherwise (7.1.5) The application of Schrage's algorithm to the constants(7.1.3)uses the values q=127773andr=2836. Here is an implementation of the Minimal Standard generator:
278 Chapter 7. Random Numbers Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copyin Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software. Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5) g of machinereadable files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America). Portable Random Number Generators Park and Miller [1] have surveyed a large number of random number generators that have been used over the last 30 years or more. Along with a good theoretical review, they present an anecdotal sampling of a number of inadequate generators that have come into widespread use. The historical record is nothing if not appalling. There is good evidence, both theoretical and empirical, that the simple multiplicative congruential algorithm Ij+1 = aIj (mod m) (7.1.2) can be as good as any of the more general linear congruential generators that have c = 0 (equation 7.1.1) — if the multiplier a and modulus m are chosen exquisitely carefully. Park and Miller propose a “Minimal Standard” generator based on the choices a = 75 = 16807 m = 231 − 1 = 2147483647 (7.1.3) First proposed by Lewis, Goodman, and Miller in 1969, this generator has in subsequent years passed all new theoretical tests, and (perhaps more importantly) has accumulated a large amount of successful use. Park and Miller do not claim that the generator is “perfect” (we will see below that it is not), but only that it is a good minimal standard against which other generators should be judged. It is not possible to implement equations (7.1.2) and (7.1.3) directly in a high-level language, since the product of a and m − 1 exceeds the maximum value for a 32-bit integer. Assembly language implementation using a 64-bit product register is straightforward, but not portable from machine to machine. A trick due to Schrage [2,3] for multiplying two 32-bit integers modulo a 32-bit constant, without using any intermediates larger than 32 bits (including a sign bit) is therefore extremely interesting: It allows the Minimal Standard generator to be implemented in essentially any programming language on essentially any machine. Schrage’s algorithm is based on an approximate factorization of m, m = aq + r, i.e., q = [m/a], r = m mod a (7.1.4) with square brackets denoting integer part. If r is small, specifically r<q, and 0 <z<m − 1, it can be shown that both a(z mod q) and r[z/q] lie in the range 0,...,m − 1, and that az mod m = a(z mod q) − r[z/q] if it is ≥ 0, a(z mod q) − r[z/q] + m otherwise (7.1.5) The application of Schrage’s algorithm to the constants (7.1.3) uses the values q = 127773 and r = 2836. Here is an implementation of the Minimal Standard generator:
7.1 Uniform Deviates 279 #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define MASK 123459876 float rano(long *idum) "Minimal"random number generator of Park and Miller.Returns a uniform random deviate between 0.0 and 1.0.Set or reset idum to any integer value (except the unlikely value MASK) to initialize the sequence;idum must not be altered between calls for successive deviates in a sequence. long k; float ans; g *idum“=MASK; XORing with MASK allows use of zero and other k=(*idum)/IQ; simple bit patterns for idum. *idum=IA*(*idum-k*IQ)-IR*k: Compute idum=(IA*idum)%IM without over- if (*idum O)*idum +IM; flows by Schrage's method. ans=AM*(*idum) Convert idum to a floating result. *idum MASK; Unmask before return. RECIPES return ans; 婆是 Press. The period of rano is 231-22.1 x 109.A peculiarity of generators of the form (7.1.2)is that the value 0 must never be allowed as the initial seed-it perpetuates itself-and it never occurs for any nonzero initial seed.Experience 9 has shown that users always manage to call random number generators with the seed idum=0.That is why rano performs its exclusive-or with an arbitrary constant both SCIENTIFIC on entry and exit.If you are the first user in history to be proofagainst human error, you can remove the two lines with the A operation. 6 Park and Miller discuss two other multipliers a that can be used with the same m =231-1.These are a =48271 (with g=44488 and r =3399)and a 69621 (with g=30845 and r=23902).These can be substituted in the routine rano if desired;they may be slightly superior to Lewis et al.'s longer-tested values.No values other than these should be used. The routine rano is a Minimal Standard,satisfactory for the majority of Recipes Numerica 10621 applications,but we do not recommend it as the final word on random number 43106 generators.Our reason is precisely the simplicity of the Minimal Standard.It is Recipes not hard to think of situations where successive random numbers might be used in a way that accidentally conflicts with the generation algorithm.For example, since successive numbers differ by a multiple of only 1.6 x 104 out of a modulus of North Software. more than 2 x 109,very small random numbers will tend to be followed by smaller than average values.One time in 105,for example,there will be a value<10-6 returned (as there should be),but this will ahways be followed by a value less than about 0.0168.One can easily think of applications involving rare events where this property would lead to wrong results. There are other,more subtle,serial correlations present in rano.For example, if successive points (Ii,I+1)are binned into a two-dimensional plane for i= 1,2,...,N,then the resulting distribution fails the x2test when N is greater than a few x107,much less than the period m-2.Since low-order serial correlations have historically been such a bugaboo,and since there is a very simple way to remove
7.1 Uniform Deviates 279 Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copyin Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software. Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5) g of machinereadable files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America). #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define MASK 123459876 float ran0(long *idum) “Minimal” random number generator of Park and Miller. Returns a uniform random deviate between 0.0 and 1.0. Set or reset idum to any integer value (except the unlikely value MASK) to initialize the sequence; idum must not be altered between calls for successive deviates in a sequence. { long k; float ans; *idum ^= MASK; XORing with MASK allows use of zero and other k=(*idum)/IQ; simple bit patterns for idum. *idum=IA*(*idum-k*IQ)-IR*k; Compute idum=(IA*idum) % IM without overif (*idum < 0) *idum += IM; flows by Schrage’s method. ans=AM*(*idum); Convert idum to a floating result. *idum ^= MASK; Unmask before return. return ans; } The period of ran0 is 231 − 2 ≈ 2.1 × 109. A peculiarity of generators of the form (7.1.2) is that the value 0 must never be allowed as the initial seed — it perpetuates itself — and it never occurs for any nonzero initial seed. Experience has shown that users always manage to call random number generators with the seed idum=0. That is why ran0 performs its exclusive-or with an arbitrary constant both on entry and exit. If you are the first user in history to be proof against human error, you can remove the two lines with the ∧ operation. Park and Miller discuss two other multipliers a that can be used with the same m = 231 − 1. These are a = 48271 (with q = 44488 and r = 3399) and a = 69621 (with q = 30845 and r = 23902). These can be substituted in the routine ran0 if desired; they may be slightly superior to Lewis et al.’s longer-tested values. No values other than these should be used. The routine ran0 is a Minimal Standard, satisfactory for the majority of applications, but we do not recommend it as the final word on random number generators. Our reason is precisely the simplicity of the Minimal Standard. It is not hard to think of situations where successive random numbers might be used in a way that accidentally conflicts with the generation algorithm. For example, since successive numbers differ by a multiple of only 1.6 × 10 4 out of a modulus of more than 2 × 109, very small random numbers will tend to be followed by smaller than average values. One time in 106, for example, there will be a value < 10−6 returned (as there should be), but this will always be followed by a value less than about 0.0168. One can easily think of applications involving rare events where this property would lead to wrong results. There are other, more subtle, serial correlations present in ran0. For example, if successive points (Ii, Ii+1) are binned into a two-dimensional plane for i = 1, 2,...,N, then the resulting distribution fails the χ2 test when N is greater than a few ×107, much less than the period m − 2. Since low-order serial correlations have historically been such a bugaboo, and since there is a very simple way to remove