/** * * Random number generator * (ported from stamp library) * * @author Hyojin Sung (sung12@cs.uiuc.edu) * */ public class RandomType { private final static long MATRIX_A = 0x9908b0df; private final static long N = 624; private final static long M = 397; private final static long UPPER_MASK = 0x80000000; /* most significant w-r bits */ private final static long LOWER_MASK = 0x7fffffff; /* least significant r bits */ private long[] mt; private long mti; RandomType() { mti = N; mt = new long[(int)mti]; init_genrand(0); } private void init_genrand(long seed) { long mti; mt[0]= seed & 0xffffffff; for (mti=1; mti<N; mti++) { mt[(int)mti] = (1812433253 * (mt[(int)mti-1] ^ (mt[(int)mti-1] >> 30)) + mti); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array mt[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ mt[(int)mti] &= 0xffffffff; /* for >32 bit machines */ } this.mti = mti; } public void random_seed(long seed) { init_genrand(seed); } public long random_generate() { long y; final long[] mag01 = {0x0, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ if (mti >= N) { /* generate N words at one time */ long kk; if (mti == N+1) /* if init_genrand() has not been called, */ init_genrand(5489); /* a default initial seed is used */ for (kk=0;kk<N-M;kk++) { y = (mt[(int)kk]&UPPER_MASK)|(mt[(int)kk+1]&LOWER_MASK); mt[(int)kk] = mt[(int)(kk+M)] ^ (y >> 1) ^ mag01[(int)y & 0x1]; } for (;kk<N-1;kk++) { y = (mt[(int)kk]&UPPER_MASK)|(mt[(int)kk+1]&LOWER_MASK); mt[(int)kk] = mt[(int)kk+(int)(M-N)] ^ (y >> 1) ^ mag01[(int)y & 0x1]; } y = (mt[(int)N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[(int)N-1] = mt[(int)M-1] ^ (y >> 1) ^ mag01[(int)y & 0x1]; mti = 0; } y = mt[(int)mti++]; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680; y ^= (y << 15) & 0xefc60000; y ^= (y >> 18); return y; } }