103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
#ifndef MY_THREADSAVE_RANDOM_GENERATOR
|
|
#define MY_THREADSAVE_RANDOM_GENERATOR
|
|
|
|
/******************************************************************************
|
|
* File: mrand.h
|
|
* Purpose: simple portable thread save random generator
|
|
* ccording to Schrage
|
|
* Author: M. Thaler, 5/2012, BSy
|
|
* Version: v.fs20
|
|
******************************************************************************/
|
|
|
|
#include <sys/time.h>
|
|
|
|
//******************************************************************************
|
|
|
|
#define MMM_MR 2147483563
|
|
#define AAA_MR 40014
|
|
#define QQQ_MR 53668
|
|
#define RRR_MR 12211
|
|
|
|
#define MRAND_MAX (MMM_MR-1)
|
|
|
|
//******************************************************************************
|
|
|
|
typedef int rand_t;
|
|
|
|
// seed ------------------------------------------------------------------------
|
|
|
|
void rand_seed(rand_t *srand, int seed) {
|
|
struct timeval prandom_seed;
|
|
gettimeofday(&prandom_seed, NULL);
|
|
if (seed > 0)
|
|
*srand = seed;
|
|
else
|
|
*srand = (prandom_seed.tv_usec);
|
|
|
|
}
|
|
|
|
// integer random value -------------------------------------------------------
|
|
// range 0 .. MRAND_MAX (inclusive)
|
|
|
|
int rand_int(rand_t *srand) {
|
|
int nx;
|
|
nx = AAA_MR * (*srand % QQQ_MR) - RRR_MR * (*srand / QQQ_MR);
|
|
*srand = (nx > 0) ? nx : nx + MMM_MR;
|
|
return (*srand);
|
|
}
|
|
|
|
// float random value ---------------------------------------------------------
|
|
// range 0.0 .. 1.0 (inclusive)
|
|
|
|
float rand_float(rand_t *srand) {
|
|
float fx;
|
|
*srand = rand_int(srand);
|
|
fx = (float)(*srand) / ((float)MRAND_MAX);
|
|
return (fx);
|
|
}
|
|
|
|
// double random value --------------------------------------------------------
|
|
// range 0.0 .. 1.0 (inclusive)
|
|
|
|
double rand_double(rand_t *srand) {
|
|
double fx;
|
|
*srand = rand_int(srand);
|
|
fx = (double)(*srand) / ((double)MRAND_MAX);
|
|
return (fx);
|
|
}
|
|
|
|
// unsigned int random range --------------------------------------------------
|
|
// range low .. high
|
|
|
|
unsigned int rand_range(unsigned int low, unsigned int high, rand_t *srand) {
|
|
unsigned int rv;
|
|
double prop;
|
|
prop = ((double)(high - low)) * rand_double(srand);
|
|
rv = low + ((unsigned int) prop);
|
|
return(rv);
|
|
}
|
|
|
|
// unsigned int probability ---------------------------------------------------
|
|
// returns 0 or 1
|
|
|
|
unsigned int rand_prob(double prob, rand_t *srand) {
|
|
if (rand_double(srand) >= 1.0-prob)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
// unsigned int toss coin -----------------------------------------------------
|
|
// returns 0 or 1
|
|
|
|
unsigned int toss_coin(rand_t *srand) {
|
|
if (rand_float(srand) >= 0.5)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
//******************************************************************************
|
|
|
|
#endif
|