1 /**************************************************************************
3 * Copyright 2012 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
36 * Variant of Mersenne Twister which can be skipped to any point in time.
38 * Instead of producing a new state table by mutating the previous table it initiates
39 * again using a seed which is the last random value of the previous state
45 static const uint32_t n
= 624;
46 static const uint32_t m
= 397;
47 static const uint32_t b32
= 1 << 31;
48 static const uint32_t rand_max
= 0xFFFFFFFF;
52 mSeed(0), mIndex(0), mState()
56 Mersenne(unsigned int seed
)
63 uint32_t x
= mState
[mIndex
++];
65 x
^= (x
<< 7) & 0x9D2C5680;
66 x
^= (x
<< 15) & 0xEFC60000;
85 sprintf(buffer
, "%08x%03d", mSeed
, mIndex
);
89 void setState(const std::string
& state
){
91 sscanf(state
.c_str(), "%08x%03d", &seed
, &index
);
97 void init(uint32_t seed
)
102 /* Standard MT initialiser */
105 for (uint32_t i
= 1; i
< n
; ++i
)
106 mState
[i
] = 1812433253 * (mState
[i
- 1] ^ (mState
[i
- 1] >> 30)) + i
;
108 /* Standard MT number generator, split into parts to avoid having to do % n */
109 for (uint32_t i
= 0; i
< (n
- m
); ++i
)
110 mState
[i
] = mState
[i
+ m
] ^ twist(mState
[i
], mState
[i
+ 1]);
112 for (uint32_t i
= n
- m
; i
< (n
- 1); ++i
)
113 mState
[i
] = mState
[i
+ m
- n
] ^ twist(mState
[i
], mState
[i
+ 1]);
115 mState
[n
- 1] = mState
[m
- 1] ^ twist(mState
[n
- 1], mState
[0]);
119 inline uint32_t twist(uint32_t a
, uint32_t b
)
121 return (((a
& b32
) | (b
& ~b32
)) >> 1) ^ ((b
& 1) ? 0x9908B0DF : 0);
130 #endif // MERSENNE_HPP