00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <limits.h>
00038 #include "SCA_RandomNumberGenerator.h"
00039
00040
00041 #define N 624
00042 #define M 397
00043 #define MATRIX_A 0x9908b0df
00044 #define UPPER_MASK 0x80000000
00045 #define LOWER_MASK 0x7fffffff
00046
00047
00048 #define TEMPERING_MASK_B 0x9d2c5680
00049 #define TEMPERING_MASK_C 0xefc60000
00050 #define TEMPERING_SHIFT_U(y) (y >> 11)
00051 #define TEMPERING_SHIFT_S(y) (y << 7)
00052 #define TEMPERING_SHIFT_T(y) (y << 15)
00053 #define TEMPERING_SHIFT_L(y) (y >> 18)
00054
00055 SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) {
00056 int mti = N + 1;
00057 m_seed = seed;
00058 SetStartVector();
00059 }
00060
00061 SCA_RandomNumberGenerator::~SCA_RandomNumberGenerator() {
00062
00063 }
00064
00065 void SCA_RandomNumberGenerator::SetStartVector(void) {
00066
00067
00068
00069
00070 mt[0] = m_seed & 0xffffffff;
00071 for (mti = 1; mti < N; mti++)
00072 mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
00073 }
00074
00075 long SCA_RandomNumberGenerator::GetSeed() { return m_seed; }
00076 void SCA_RandomNumberGenerator::SetSeed(long newseed)
00077 {
00078 m_seed = newseed;
00079 SetStartVector();
00080 }
00081
00085 unsigned long SCA_RandomNumberGenerator::Draw() {
00086 static unsigned long mag01[2] = { 0x0, MATRIX_A };
00087
00088
00089 unsigned long y;
00090
00091 if (mti >= N) {
00092 int kk;
00093
00094
00095
00096
00097
00098 for (kk = 0; kk < N - M; kk++) {
00099 y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
00100 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
00101 }
00102 for (; kk < N-1; kk++) {
00103 y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
00104 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
00105 }
00106 y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
00107 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
00108
00109 mti = 0;
00110 }
00111
00112 y = mt[mti++];
00113 y ^= TEMPERING_SHIFT_U(y);
00114 y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
00115 y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
00116 y ^= TEMPERING_SHIFT_L(y);
00117
00118 return y;
00119 }
00120
00121 float SCA_RandomNumberGenerator::DrawFloat() {
00122 return ( (float) Draw()/ (unsigned long) 0xffffffff );
00123 }
00124
00125