mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mt19937ar.c
00001 /* 00002 ** mt19937ar.c - MT Random functions 00003 ** 00004 ** See Copyright Notice in mruby.h 00005 */ 00006 00007 #include "mruby.h" 00008 #include "mt19937ar.h" 00009 00010 /* Period parameters */ 00011 /* #define N 624 */ 00012 #define M 397 00013 #define MATRIX_A 0x9908b0dfUL /* constant vector a */ 00014 #define UPPER_MASK 0x80000000UL /* most significant w-r bits */ 00015 #define LOWER_MASK 0x7fffffffUL /* least significant r bits */ 00016 00017 #if 0 /* dead_code */ 00018 static unsigned long mt[N]; /* the array for the state vector */ 00019 static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ 00020 #endif /* dead_code */ 00021 00022 void mrb_random_init_genrand(mt_state *t, unsigned long s) 00023 { 00024 t->mt[0]= s & 0xffffffffUL; 00025 for (t->mti=1; t->mti<N; t->mti++) { 00026 t->mt[t->mti] = 00027 (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti); 00028 t->mt[t->mti] &= 0xffffffffUL; 00029 } 00030 } 00031 00032 unsigned long mrb_random_genrand_int32(mt_state *t) 00033 { 00034 unsigned long y; 00035 static const unsigned long mag01[2]={0x0UL, MATRIX_A}; 00036 /* mag01[x] = x * MATRIX_A for x=0,1 */ 00037 00038 if (t->mti >= N) { /* generate N words at one time */ 00039 int kk; 00040 00041 if (t->mti == N+1) /* if init_genrand() has not been called, */ 00042 mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */ 00043 00044 for (kk=0;kk<N-M;kk++) { 00045 y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); 00046 t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00047 } 00048 for (;kk<N-1;kk++) { 00049 y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK); 00050 t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00051 } 00052 y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK); 00053 t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00054 00055 t->mti = 0; 00056 } 00057 00058 y = t->mt[t->mti++]; 00059 00060 /* Tempering */ 00061 y ^= (y >> 11); 00062 y ^= (y << 7) & 0x9d2c5680UL; 00063 y ^= (y << 15) & 0xefc60000UL; 00064 y ^= (y >> 18); 00065 00066 t->gen.int_ = y; 00067 00068 return y; 00069 } 00070 00071 double mrb_random_genrand_real1(mt_state *t) 00072 { 00073 mrb_random_genrand_int32(t); 00074 t->gen.double_ = t->gen.int_*(1.0/4294967295.0); 00075 return t->gen.double_; 00076 /* divided by 2^32-1 */ 00077 } 00078 00079 #if 0 /* dead_code */ 00080 /* initializes mt[N] with a seed */ 00081 void init_genrand(unsigned long s) 00082 { 00083 mt[0]= s & 0xffffffffUL; 00084 for (mti=1; mti<N; mti++) { 00085 mt[mti] = 00086 (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 00087 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 00088 /* In the previous versions, MSBs of the seed affect */ 00089 /* only MSBs of the array mt[]. */ 00090 /* 2002/01/09 modified by Makoto Matsumoto */ 00091 mt[mti] &= 0xffffffffUL; 00092 /* for >32 bit machines */ 00093 } 00094 } 00095 00096 /* initialize by an array with array-length */ 00097 /* init_key is the array for initializing keys */ 00098 /* key_length is its length */ 00099 /* slight change for C++, 2004/2/26 */ 00100 void init_by_array(unsigned long init_key[], int key_length) 00101 { 00102 int i, j, k; 00103 init_genrand(19650218UL); 00104 i=1; j=0; 00105 k = (N>key_length ? N : key_length); 00106 for (; k; k--) { 00107 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) 00108 + init_key[j] + j; /* non linear */ 00109 mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ 00110 i++; j++; 00111 if (i>=N) { mt[0] = mt[N-1]; i=1; } 00112 if (j>=key_length) j=0; 00113 } 00114 for (k=N-1; k; k--) { 00115 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) 00116 - i; /* non linear */ 00117 mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ 00118 i++; 00119 if (i>=N) { mt[0] = mt[N-1]; i=1; } 00120 } 00121 00122 mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 00123 } 00124 00125 /* generates a random number on [0,0xffffffff]-interval */ 00126 unsigned long genrand_int32(void) 00127 { 00128 unsigned long y; 00129 static const unsigned long mag01[2]={0x0UL, MATRIX_A}; 00130 /* mag01[x] = x * MATRIX_A for x=0,1 */ 00131 00132 if (mti >= N) { /* generate N words at one time */ 00133 int kk; 00134 00135 if (mti == N+1) /* if init_genrand() has not been called, */ 00136 init_genrand(5489UL); /* a default initial seed is used */ 00137 00138 for (kk=0;kk<N-M;kk++) { 00139 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 00140 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00141 } 00142 for (;kk<N-1;kk++) { 00143 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 00144 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00145 } 00146 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); 00147 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00148 00149 mti = 0; 00150 } 00151 00152 y = mt[mti++]; 00153 00154 /* Tempering */ 00155 y ^= (y >> 11); 00156 y ^= (y << 7) & 0x9d2c5680UL; 00157 y ^= (y << 15) & 0xefc60000UL; 00158 y ^= (y >> 18); 00159 00160 return y; 00161 } 00162 00163 /* generates a random number on [0,0x7fffffff]-interval */ 00164 long genrand_int31(void) 00165 { 00166 return (long)(genrand_int32()>>1); 00167 } 00168 00169 /* generates a random number on [0,1]-real-interval */ 00170 double genrand_real1(void) 00171 { 00172 return genrand_int32()*(1.0/4294967295.0); 00173 /* divided by 2^32-1 */ 00174 } 00175 00176 /* generates a random number on [0,1)-real-interval */ 00177 double genrand_real2(void) 00178 { 00179 return genrand_int32()*(1.0/4294967296.0); 00180 /* divided by 2^32 */ 00181 } 00182 00183 /* generates a random number on (0,1)-real-interval */ 00184 double genrand_real3(void) 00185 { 00186 return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); 00187 /* divided by 2^32 */ 00188 } 00189 00190 /* generates a random number on [0,1) with 53-bit resolution*/ 00191 double genrand_res53(void) 00192 { 00193 unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 00194 return(a*67108864.0+b)*(1.0/9007199254740992.0); 00195 } 00196 /* These real versions are due to Isaku Wada, 2002/01/09 added */ 00197 #endif /* dead_code */ 00198
Generated on Tue Jul 12 2022 18:00:34 by 1.7.2