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), rand(3C), rand(3V), 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 generator function determines when it is more efficient (faster) to use lcrans(3M) versus addrans(3M). For normal use (more than 50 calls), use addrans(3M), possibly in conjunction with shufrans(3M), rather than calls to lcrans(3M), drand48(3), rand(3C), rand(3V) 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).