1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
/*! \file random.c
\brief A portable random number generator.
\author Copyright (c) 2000 Markus L. Noga <markus@noga.de>
See Numerical Recipes in C 2nd Edition, p. 279-281 for inspiration.
*/
//#include <stdlib.h>
/////////////////////////////////////////////////////////////////////////////
//
// Definitions
//
/////////////////////////////////////////////////////////////////////////////
#define PRANDOM_SLOTS 16
#define PRANDOM_MASK 0x3fc91ab4
#define PRANDOM_A 16807
#define PRANDOM_M 2147483647
#define PRANDOM_Q 127773
#define PRANDOM_R 2836
//! A pseudo-random number generator
typedef struct {
long select;
long state;
long entry[PRANDOM_SLOTS];
} prandom_t;
/////////////////////////////////////////////////////////////////////////////
//
// Static variables
//
/////////////////////////////////////////////////////////////////////////////
static prandom_t generator; //!< the generator used.
/////////////////////////////////////////////////////////////////////////////
//
// Global functions
//
/////////////////////////////////////////////////////////////////////////////
//! a primitive randomizing step, using a linear congruential generator.
void randstep(long *val) {
long k;
k=(*val)/PRANDOM_Q;
*val=PRANDOM_A*(*val-k*PRANDOM_Q)-PRANDOM_R*k;
if(*val<0)
*val += PRANDOM_M;
}
//! Initialize pseudo-random number generator from seed.
void srandom(unsigned _seed) {
unsigned i;
unsigned long seed=_seed;
// catch zero seeds etc.
seed= (seed==PRANDOM_MASK) ? seed : seed^PRANDOM_MASK;
// initialize array.
randstep(&seed);
generator.select=seed & (PRANDOM_SLOTS-1);
for(i=0; i<PRANDOM_SLOTS; i++) {
randstep(&seed);
generator.entry[i]=seed;
}
randstep(&seed);
generator.state=seed;
}
//! Return a pseudo-random number in the range of MIN_INT to MAX_INT.
long random() {
long res=generator.entry[generator.select];
randstep(&generator.state);
generator.entry[generator.select]=generator.state;
generator.select=res & (PRANDOM_SLOTS-1);
return res;
}
|