Man Page lcrans.3m
NAME
lcrans - linear congruential pseudo-random number generators
SYNOPSIS
cc [ flag ... ] file ... -lsunmath -lm [ library ... ]
#include <sunmath.h>
#define LCRAN_MULTIPLIER 16807
#define LCRAN_MODULUS 2147483647L
int i_lcran_(void);
float r_lcran_(void);
double d_lcran_(void);
void i_lcrans_(int *x, int *n, int *l, int *u);
void u_lcrans_(unsigned *x, int *n, unsigned *l, unsigned
*u);
void r_lcrans_(float *x, int *n, float *l, float *u);
void d_lcrans_(double *x, int *n, double *l, double *u);
void i_get_lcrans_(int *x);
void i_set_lcrans_(int *x);
void i_init_lcrans_(void);
DESCRIPTION
These functions provide uniform random variates, of types
integer, single-precision floating-point, or double-
precision floating-point.
Linear congruential variates are generated one at a time by
..._lcran_() using the recurrence
lcran_last = (LCRAN_MULTIPLIER * lcran_last) % LCRAN_MODULUS
i_lcran_() returns lcran_last, while r_lcran_() and
d_lcran_() return lcran_last / LCRAN_MODULUS, so that the
variates are contained in the following intervals:
type | lower bound | upper bound
| name value| name value
_______|________________________________________|_____________________________________
integer| I_LCRAN_LB 1| I_LCRAN_UB 2147483646
float | R_LCRAN_LB 4.656612873077392578E-10| R_LCRAN_UB 1
double | D_LCRAN_LB 4.656612875245796923E-10| D_LCRAN_UB 0.9999999995343387127
lcran_last should satisfy 1 <= lcran_last <= 2147483646, but
for efficiency ..._lcran_() does not check that.
Linear congruential variates are generated *n at a time by
..._lcrans_() using the recurrence
lcran_last = (lcran_multiplier * lcran_last) % LCRAN_MODULUS ;
return scale * (lcran_last + offset) ;
where scale and offset are calculated from *l and *u so that
the computed variates are uniform in [*l,*u]. Thus changing
lcran_multiplier changes the variates produced by
..._lcrans_(), but for efficiency ..._lcran_() uses the
fixed LCRAN_MULTIPLIER, 16807. The fixed modulus
LCRAN_MODULUS, 2147483647L, is intentionally not a power of
two to avoid the defects in rand(3C). On entry,
..._lcrans_() does check that 1 <= lcran_last <= 2147483646
and modifies lcran_last if necessary.
The state of the linear congruential generator (an array of
two ints containing lcran_last and lcran_multiplier) may be
obtained with i_get_lcrans_() and set with i_set_lcrans_().
The initial state may be restored with i_init_lcrans_().
EXAMPLES
to generate 1000 double-precision random variates in (0,1)
double x[1000] ; int i, n = 1000 ;
double lb = D_LCRAN_LB, ub = D_LCRAN_UB ;
for (i=0;i<n;i++) x[i] = d_lcran_(); /* or... */
d_lcrans_(x, &n, &lb, &ub) ; /* same output, but more efficient */
to generate 1000 integer random variates in [-10,+10]
int x[1000] ; int n = 1000, lb = -10, ub = 10 ;
i_lcrans_(x, &n, &lb, &ub) ;
SEE ALSO
addrans(3M), drand48(3), mwcrans(3M), rand(3C), rand(3C),
random(3), shufrans(3M).
Knuth, Seminumerical Algorithms, 1981, Addison-Wesley.
Park and Miller, Random Number Generators: Good Ones are
Hard to Find, Communications of the ACM, October 1988.
NOTES
The number of times your program calls a random number gen-
erator function determines when it is more efficient (fas-
ter) to use lcrans(3M) versus addrans(3M). For normal use
(more than 50 calls), use addrans(3M), possibly in conjunc-
tion with shufrans(3M), rather than calls to lcrans(3M),
drand48(3), rand(3C), rand(3C) and random(3). For casual
use (less than 50 calls), use lcrans(3M) rather than
addrans(3M). The reason for this is that the first call to
addrans(3M) has the overhead cost of initializing a table of
55 elements (defined by ADDRAN_SIZE).