0001: //--------------------------------------------------------------------------------------
0002: // File: CRand.h
0003: //
0004: // Mersenne Twister擬似乱数発生法による乱数
0005: //
0006: // Copyright (c) Takashi Imagire. All rights reserved.
0007: // Mersenne Twister : Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved.
0008: //--------------------------------------------------------------------------------------
0009: #ifndef __CRAND_H_
0010: #define __CRAND_H_
0011: 
0012: #include "MyTypes.h"
0013: 
0014: #define N 624
0015: #define M 397
0016: #define MATRIX_A 0x9908b0dfUL   /* constant vector a */
0017: #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
0018: #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
0019: 
0020: 
0021: class CRand
0022: {
0023: private:
0024:     void Init( u32 seed );
0025: 
0026:     u32 mt[N];   /* the array for the state vector  */
0027:     s32 mti; 
0028: 
0029: public:
0030:     // コンストラクタ
0031:     CRand( u32 seed = 0 );
0032:     
0033:     // 擬似乱数を所得する
0034:     u32    GetU32(void);
0035:     double GetF32(void);
0036: };
0037: 
0038: 
0039: // ---------------------------------------------------------------------------
0040: inline CRand::CRand( u32 seed )
0041: {
0042:     mti = N+1; /* mti==N+1 means mt[N] is not initialized */
0043:     Init( seed );
0044: }
0045: 
0046: // ---------------------------------------------------------------------------
0047: inline void CRand::Init( u32 s )
0048: {
0049:     mt[0]= s & 0xffffffff;
0050:     for (mti=1; mti<N; mti++) {
0051:         mt[mti] = 
0052:         (1812433253 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
0053:         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
0054:         /* In the previous versions, MSBs of the seed affect   */
0055:         /* only MSBs of the array mt[].                        */
0056:         /* 2002/01/09 modified by Makoto Matsumoto             */
0057:         mt[mti] &= 0xffffffff;
0058:         /* for >32 bit machines */
0059:     }
0060: }
0061: 
0062: // ---------------------------------------------------------------------------
0063: inline u32 CRand::GetU32(void)
0064: {
0065:     u32 y;
0066:     static u32 mag01[2]={0x0UL, MATRIX_A};
0067:     /* mag01[x] = x * MATRIX_A  for x=0,1 */
0068: 
0069:     if (mti >= N) { /* generate N words at one time */
0070:         int kk;
0071: 
0072:         if (mti == N+1)   /* if init_genrand() has not been called, */
0073:             Init(5489UL); /* a default initial seed is used */
0074: 
0075:         for (kk=0;kk<N-M;kk++) {
0076:             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
0077:             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
0078:         }
0079:         for (;kk<N-1;kk++) {
0080:             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
0081:             mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
0082:         }
0083:         y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
0084:         mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
0085: 
0086:         mti = 0;
0087:     }
0088:   
0089:     y = mt[mti++];
0090: 
0091:     /* Tempering */
0092:     y ^= (y >> 11);
0093:     y ^= (y <<  7) & 0x9d2c5680;
0094:     y ^= (y << 15) & 0xefc60000;
0095:     y ^= (y >> 18);
0096: 
0097:     return y;
0098: }
0099: 
0100: // ---------------------------------------------------------------------------
0101: // 一様実乱数[0,1) (32ビット精度)
0102: double CRand::GetF32(void)
0103: {
0104:     return GetU32()*(1.0/4294967296.0); 
0105:     /* 2^32 で割る */
0106: }
0107: 
0108: 
0109: #endif // !__RAND_H_
0110: