I'm wrapping Prelude's implementation of jsw_rand inside a class. So far this is what I have:
CRand.h
PHP Code:
#ifndef CLASS_RANDOM_GENERATOR_H
#define CLASS_RANDOM_GENERATOR_H
/*
Random number Class
- Wrapped around Julienne Walker's implementation of Mersenne Twister's found at
http://eternallyconfuzzled.com/brain.html, as of July, 18, 2006
- Slightly altered to accomodate the class implementation
*/
class CRand {
private:
static unsigned int time_seed();
static const int N = 624;
static const int M = 397;
static const unsigned long A = 0x9908b0dfUL;
static const unsigned long U = 0x80000000UL;
static const unsigned long L = 0x7fffffffUL;
public:
explicit CRand(unsigned long, unsigned long);
// TODO: void reseed(unsigned long = time_seed());
// TODO: unsigned long rethrow();
private:
void seed(unsigned long = time_seed());
// TODO: unsigned long generate();
unsigned long low_;
unsigned long high_;
unsigned long res_; //holds random
// internal state (per object)
unsigned long x[N];
int next;
};
#endif // CLASS_RANDOM_GENERATOR_H
CRand.cpp
PHP Code:
#include <climits>
#include <ctime>
#include "crand.h"
CRand::CRand(unsigned long low, unsigned long high): low_(low), high_(high) {
if(low_ > high_) {
low_ = high;
high_ = low;
}
if( low_ != high_ ) {
seed();
//TODO: res_ = generate();
} else res_ = low_;
}
unsigned int CRand::time_seed() {
std::time_t now = std::time(0);
unsigned char *p = (unsigned char *)&now;
unsigned seed = 0;
std::size_t i;
for (i = 0; i < sizeof now; i++)
seed = seed * ( UCHAR_MAX + 2U ) + p[i];
return seed;
}
/* Initialize internal state */
void CRand::seed(unsigned long s) {
int i;
x[0] = s & 0xffffffffUL;
for ( i = 1; i < N; i++ ) {
x[i] = ( 1812433253UL
* ( x[i - 1] ^ ( x[i - 1] >> 30 ) ) + i );
x[i] &= 0xffffffffUL;
}
}
I'm about to implement the actual jsw_rand() algorithm into the class. However, I'm afraid I couldn't fully understand the discussion about distribution found at http://eternallyconfuzzled.com/articles/rand.html.
My question is, will it be ok, after using Prelude's algorithm jsw_rand(), to use the modulos operator to bring the resulting long into the range defined by my data members low_ and high_? Or should I instead use the uniform deviation she discusses?
Basically... since I'm having an hard time interpreting the code inside jsw_rand() (and because math is not one of my best attributes) I'm at loss as to which it already provides a distribution safeguard(?). My guess is it doesn't and I should either call it repeatedly or provide a uniform deviation algorithm as she discusses.