Author: Andreas Stabel
Date: 06:08:21 10/21/98
Go up one level in this thread
On October 19, 1998 at 01:22:10, Dann Corbit wrote: >Arguably, the best available prng is the Mersenne Twister. It is extremely fast >and has a ludicrously long period before it repeats. It passes DIEHARD with >flying colors. A number of technical papers have been written on the subject. >A web search should turn up plenty. I've downloaded the Mersenne Twister and made it into a simple single file C program, so if anybody is interrested - here it is: // A C-program for MT19937: // lRand() generates one pseudorandom unsigned integer (32bit) // which is uniformly distributed among 0 to 2^32-1 // dRand() generates one pseudorandom real number // which is uniformly distributed among 0.0 to <1.0 // Coded by Takuji Nishimura, considering the suggestions by // Topher Cooper and Marc Rieffel in July-Aug. 1997. // Modified by John Cooke 1998-04-20 // to use standard Seed(), lRand(), dRand() functions // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Library General Public License for more details. // You should have received a copy of the GNU Library General // Public License along with this library; if not, write to the // Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA // 02111-1307 USA // Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. // When you use this, send an email to: matumoto@math.keio.ac.jp // with an appropriate reference to your work. #include <stdio.h> #include <time.h> // Period parameters #define MT_BUFSZ 624 #define N MT_BUFSZ #define M 397 #define MATRIX_A 0x9908b0df // constant vector a #define UPPER_MASK 0x80000000 // most significant w-r bits #define LOWER_MASK 0x7fffffff // least significant r bits // Tempering parameters #define TEMPERING_MASK_B 0x9d2c5680 #define TEMPERING_MASK_C 0xefc60000 #define TEMPERING_SHIFT_U(y) (y >> 11) #define TEMPERING_SHIFT_S(y) (y << 7) #define TEMPERING_SHIFT_T(y) (y << 15) #define TEMPERING_SHIFT_L(y) (y >> 18) typedef unsigned long uint32; uint32 mt[MT_BUFSZ]; /* the array for the state vector */ int mti; uint32 mag01[2]; /* mag01[x] = x * MATRIX_A for x=0,1 */ void Seed ( uint32 seed) { // setting initial seeds to mt[N] using // the generator Line 25 of Table 1 in // [KNUTH 1981, The Art of Computer Programming // Vol. 2 (2nd Ed.), pp102] // fudge the seed if it is zero mt[0] = seed ? seed : 0xffffffff; for (mti=1; mti<N; mti++) mt[mti] = (69069 * mt[mti-1]); mag01[0] = 0x0; mag01[1] = MATRIX_A; } uint32 lRand() { uint32 y; if (mti >= N) { // generate N words at one time int kk; for (kk=0;kk<N-M;kk++) { y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; } for (;kk<N-1;kk++) { y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; } y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; mti = 0; } y = mt[mti++]; y ^= TEMPERING_SHIFT_U(y); y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; y ^= TEMPERING_SHIFT_L(y); return y; } // RANGE_LE1 puts a uint32 in the range [0,1] (0<=x<=1) #define RANGE_LE1 2.3283064365386963e-10 // RANGE_LT1 puts a uint32 in the range [0,1) (0<=x<1) #define RANGE_LT1 2.3283064370807974e-10 double dRand () { uint32 y = lRand(); return ( (double)y * RANGE_LT1 ); // reals: [0,1)-interval }
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.