% plain TeX \def\cmd#1{\leavevmode\hbox{\tt\string#1}} \edef\{{\string{} \edef\}{\string}} \noindent{\bf RANDOM.TEX }\qquad\qquad ver 0.2 \qquad\qquad (Donald Arseneau) \bigskip \noindent Generating ``random'' numbers in \TeX. \medskip {\tt \string\setrannum \thinspace\{$\langle \it counter\rangle$\}\thinspace\{$\langle\it minimum\rangle$\}\thinspace\{$\langle\it maximum\rangle$\}} {\tt \string\setrandimen \thinspace\{$\langle \hbox{\it dimen-register}\rangle$\}\thinspace\{$\langle\it minimum\rangle$\}\thinspace\{$\langle\it maximum\rangle$\}} \medskip \noindent This software is released to the public domain. \bigskip \noindent Random integers are generated in the range 1 to 2147483646 by the macro \cmd\nextrandom. The result is returned in the counter \cmd\randomi. Do not change \cmd\randomi\ except, perhaps, to initialize it at some random (or specific) value. If you do not initialize it, it will be initialized using the time and date. (This is a sparse initialization, giving fewer than a million different starting values, but you should use other sources of numbers if they are available---just remember that most of the numbers available to \TeX\ are not at all random.) The \cmd\nextrandom\ command is not very useful by itself, unless you have exactly 2147483646 things to choose from. Much more useful is the \cmd\setrannum\ command which sets a given counter to a random value within a specified range. There are three parameters: \medskip {\tt \string\setrannum \thinspace\{$\langle \it counter\rangle$\}\thinspace\{$\langle\it minimum\rangle$\}\thinspace\{$\langle\it maximum\rangle$\}} \medskip \noindent For example, to simulate a die-roll: \medskip {\tt \string\setrannum\{\string\die\}\{1\}\{6\} \string\ifcase\string\die...} \medskip If you need random numbers that are not integers, you will have to use dimen registers instead with \cmd\setrandimen. For example, to set a random page width between 3 and 6.5 inches: \medskip \cmd\setrandimen \cmd\hsize{\tt\{3in\}\{6.5in\}} \medskip\noindent The ``\cmd\pointless'' macro will remove the ``{\tt pt}'' that \TeX\ gives so you can use the dimensions as pure ``real'' numbers. In that case, specify the range in {\tt pt} units. For example, \medskip {\tt\string\setrandimen\string\answer\{2.71828pt\}\{3.14159pt\}} \hfill\break\indent {\tt The answer is \string\pointless\string\answer.} \medskip The random number generator is the one by Lewis, Goodman, and Miller (1969) and used as ``ran0'' in ``Numerical Recipies'' using Schrage's method for avoiding overflows. The multiplier is 16807 ($7^5$), the added constant is 0, and the modulus is 2147483647 ($2^{31}-1$). See CACM, Vol.~36, no. 7, (July 1993), p.~109. The original authors Park and Miller have since concluded that a better multiplier is 48271, rather than their original 16807. The range of integers generated is $1 - 2147483646$. A smaller range would reduce the complexity of the macros a bit, but not much---most of the code deals with initialization and type-conversion. On the other hand, the large range may be wasted due to the sparse seed initialization. \bye