Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
/*
2
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
3
All rights reserved.                          
4
 
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions
7
are met:
8
 
9
1. Redistributions of source code must retain the above copyright
10
notice, this list of conditions and the following disclaimer.
11
 
12
2. Redistributions in binary form must reproduce the above copyright
13
notice, this list of conditions and the following disclaimer in the
14
documentation and/or other materials provided with the distribution.
15
 
16
3. The names of its contributors may not be used to endorse or promote
17
products derived from this software without specific prior written
18
permission.
19
 
20
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
 
32
 
33
Any feedback is very welcome.
34
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
35
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
36
*/
37
 
38
#include <windows.h> 
39
#include "MTRand.h"
40
#include "Debug.h"
41
#include <stdio.h>
42
 
43
using namespace Sexy;
44
 
45
/* Period parameters */  
46
#define MTRAND_M 397
47
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
48
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
49
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
50
 
51
/* Tempering parameters */  
52
#define TEMPERING_MASK_B 0x9d2c5680
53
#define TEMPERING_MASK_C 0xefc60000
54
#define TEMPERING_SHIFT_U(y)  (y >> 11)
55
#define TEMPERING_SHIFT_S(y)  (y << 7)
56
#define TEMPERING_SHIFT_T(y)  (y << 15)
57
#define TEMPERING_SHIFT_L(y)  (y >> 18)
58
 
59
 
60
MTRand::MTRand(const std::string& theSerialData)
61
{
62
        SRand(theSerialData);
63
        mti=MTRAND_N+1; /* mti==MTRAND_N+1 means mt[MTRAND_N] is not initialized */
64
}
65
 
66
MTRand::MTRand(unsigned long seed)    
67
{
68
        SRand(seed);
69
}
70
 
71
MTRand::MTRand()
72
{
73
        SRand(4357);
74
}
75
 
76
static int gRandAllowed = 0;
77
void MTRand::SetRandAllowed(bool allowed)
78
{
79
        if (allowed)
80
        {
81
                if (gRandAllowed>0)
82
                        gRandAllowed--;
83
                else
84
                        DBG_ASSERT(false); // mismatched calls
85
        }
86
        else
87
                gRandAllowed++;
88
}
89
 
90
void MTRand::SRand(const std::string& theSerialData)
91
{
92
        if (theSerialData.size() == MTRAND_N*4)
93
        {
94
                memcpy(mt, theSerialData.c_str(), MTRAND_N*4);
95
        }
96
        else
97
                SRand(4357);
98
}
99
 
100
void MTRand::SRand(unsigned long seed)
101
{
102
        if (seed == 0)
103
                seed = 4357;
104
 
105
        /* setting initial seeds to mt[MTRAND_N] using         */
106
    /* the generator Line 25 of Table 1 in          */
107
    /* [KNUTH 1981, The Art of Computer Programming */
108
    /*    Vol. 2 (2nd Ed.), pp102]                  */
109
        mt[0]= seed & 0xffffffffUL;
110
        for (mti=1; mti< MTRAND_N; mti++)
111
        {
112
                mt[mti] =
113
                        (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
114
                /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
115
                /* In the previous versions, MSBs of the seed affect   */
116
                /* only MSBs of the array mt[].                        */
117
                /* 2002/01/09 modified by Makoto Matsumoto             */
118
                mt[mti] &= 0xffffffffUL;
119
                /* for >32 bit machines */
120
        }
121
}
122
 
123
unsigned long MTRand::Next()
124
{
125
        DBG_ASSERT(gRandAllowed==0);
126
        return NextNoAssert();
127
}
128
 
129
unsigned long MTRand::NextNoAssert()
130
{
131
    unsigned long y;
132
    static unsigned long mag01[2]={0x0, MATRIX_A};
133
    /* mag01[x] = x * MATRIX_A  for x=0,1 */
134
 
135
        if (mti >= MTRAND_N) { /* generate MTRAND_N words at one time */
136
                int kk;
137
 
138
                for (kk=0;kk<MTRAND_N-MTRAND_M;kk++) {
139
                        y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
140
                        mt[kk] = mt[kk+MTRAND_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
141
                }
142
                for (;kk<MTRAND_N-1;kk++) {
143
                        y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
144
                        mt[kk] = mt[kk+(MTRAND_M-MTRAND_N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
145
                }
146
                y = (mt[MTRAND_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
147
                mt[MTRAND_N-1] = mt[MTRAND_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
148
 
149
                mti = 0;
150
        }
151
 
152
    y = mt[mti++];
153
    y ^= TEMPERING_SHIFT_U(y);
154
    y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
155
    y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
156
    y ^= TEMPERING_SHIFT_L(y);
157
 
158
        y &= 0x7FFFFFFF;               
159
 
160
        /*char aStr[256];
161
        sprintf(aStr, "Rand=%d\r\n", y);
162
        OutputDebugString(aStr);*/
163
 
164
    return y;
165
}
166
 
167
unsigned long MTRand::NextNoAssert(unsigned long range)
168
{
169
        return NextNoAssert() % range;
170
}
171
 
172
unsigned long MTRand::Next(unsigned long range)
173
{
174
        DBG_ASSERT(gRandAllowed==0);
175
        return NextNoAssert( range );
176
}
177
 
178
float MTRand::NextNoAssert(float range)
179
{
180
        return (float) ((double)NextNoAssert() / (double)0x7FFFFFFF * range);
181
}
182
 
183
float MTRand::Next(float range)
184
{
185
        DBG_ASSERT(gRandAllowed==0);
186
        return NextNoAssert(range);
187
}
188
 
189
std::string MTRand::Serialize()
190
{
191
        std::string aString;
192
 
193
        aString.resize(MTRAND_N*4);
194
        memcpy((char*) aString.c_str(), mt, MTRAND_N*4);
195
 
196
        return aString;
197
}