00001 #include "random.h" 00002 #include <time.h> 00003 00004 00005 void MSLRandomSource::init_table() 00006 { 00007 table[ 0] = -1708027847; 00008 table[ 1] = 853131300; 00009 table[ 2] = -1687801470; 00010 table[ 3] = 1570894658; 00011 table[ 4] = -566525472; 00012 table[ 5] = -552964171; 00013 table[ 6] = -251413502; 00014 table[ 7] = 1223901435; 00015 table[ 8] = 1950999915; 00016 table[ 9] = -1095640144; 00017 table[10] = -1420011240; 00018 table[11] = -1805298435; 00019 table[12] = -1943115761; 00020 table[13] = -348292705; 00021 table[14] = -1323376457; 00022 table[15] = 759393158; 00023 table[16] = -630772182; 00024 table[17] = 361286280; 00025 table[18] = -479628451; 00026 table[19] = -1873857033; 00027 table[20] = -686452778; 00028 table[21] = 1873211473; 00029 table[22] = 1634626454; 00030 table[23] = -1399525412; 00031 table[24] = 910245779; 00032 table[25] = -970800488; 00033 table[26] = -173790536; 00034 table[27] = -1970743429; 00035 table[28] = -173171442; 00036 table[29] = -1986452981; 00037 table[30] = 670779321; 00038 00039 ptr0 = table; 00040 ptr1 = table + 3; 00041 ptr_end = table + 31; 00042 } 00043 00044 00045 void MSLRandomSource::set_seed(int x) 00046 { table[0] = (unsigned)x; 00047 int i; 00048 for(i=1; i<31; i++) table[i] = 1103515245 * table[i-1] + 12345; 00049 ptr0 = table; 00050 ptr1 = table + 3; 00051 for(i=0; i<310; i++) get_rand31(); 00052 } 00053 00054 00055 #define RANDMAX 0x7FFFFFFF 00056 00057 unsigned long MSLRandomSource::get_rand31() 00058 { *ptr1 += *ptr0; 00059 long i = (*ptr1 >> 1) & 0x7fffffff; 00060 if (++ptr0 >= ptr_end) ptr0 = table; 00061 if (++ptr1 >= ptr_end) ptr1 = table; 00062 return (unsigned long)i; 00063 } 00064 00065 unsigned long MSLRandomSource::get_rand32() 00066 { if (buffer == 0x00000001) buffer = 0x80000000 | get_rand31(); 00067 unsigned long result = get_rand31(); 00068 if (buffer&1) result |= 0x80000000; 00069 buffer >>= 1; 00070 return result; 00071 } 00072 00073 00074 00075 int MSLRandomSource::count = 0; 00076 00077 MSLRandomSource::MSLRandomSource() 00078 { init_table(); 00079 time_t seed; 00080 time(&seed); 00081 count++; 00082 set_seed(int(seed)*count); 00083 pat = 0xFFFFFFFF; 00084 prec = 31; 00085 bit_mode = true; 00086 low = diff = 0; 00087 buffer = 0x00000001; 00088 } 00089 00090 MSLRandomSource::MSLRandomSource(int bits) 00091 { init_table(); 00092 time_t seed; 00093 time(&seed); 00094 count++; 00095 set_seed(int(seed)*count); 00096 if (bits <= 0 || bits >= 32) 00097 pat = 0xFFFFFFFF; 00098 else 00099 pat = (1 << bits) - 1; 00100 prec = bits; 00101 bit_mode = true; 00102 low = diff = 0; 00103 buffer = 0x00000001; 00104 } 00105 00106 void MSLRandomSource::set_range(int l, int h) 00107 { low = l; 00108 diff = (h < l) ? 0 : h-l; 00109 bit_mode = false; 00110 pat = 1; 00111 while (pat <= unsigned(diff)) pat <<= 1; 00112 pat--; 00113 } 00114 00115 00116 MSLRandomSource::MSLRandomSource(int l, int h) 00117 { init_table(); 00118 time_t seed; 00119 time(&seed); 00120 count++; 00121 set_seed(int(seed)*count); 00122 set_range(l,h); 00123 buffer = 0x00000001; 00124 } 00125 00126 00127 int MSLRandomSource::set_precision(int bits) 00128 { int oldprec = prec; 00129 prec = bits; 00130 if (0 >= bits || bits >= 32) 00131 pat = 0xFFFFFFFF; 00132 else 00133 pat = (1 << bits) - 1; 00134 bit_mode = true; 00135 return oldprec; 00136 } 00137 00138 00139 int MSLRandomSource::operator()() 00140 { unsigned long x = get_rand31() & pat; 00141 if (bit_mode) 00142 return int(x); 00143 else 00144 { while (x > unsigned(diff)) x = get_rand31() & pat; 00145 return (int)(low + x); 00146 } 00147 } 00148 00149 int MSLRandomSource::operator()(int bits) 00150 { unsigned long mask = (1<<bits) - 1; 00151 int shift = 31 - bits; 00152 if (shift < 0) shift = 0; 00153 return int((get_rand31() >> shift) & mask); 00154 } 00155 00156 00157 int MSLRandomSource::operator()(int l, int h) 00158 { if (h < l) return 0; 00159 00160 int old_low = low; 00161 int old_diff = diff; 00162 unsigned long old_pat = pat; 00163 bool old_bit_mode = bit_mode; 00164 00165 set_range(l,h); 00166 int x = operator()(); 00167 00168 low = old_low; 00169 diff = old_diff; 00170 pat = old_pat; 00171 bit_mode = old_bit_mode; 00172 00173 return x; 00174 } 00175 00176 00177 00178 MSLRandomSource& MSLRandomSource::operator>>(bool& x) 00179 { x = (get_rand31() & (1<<16)) != 0; 00180 return *this; 00181 } 00182 00183 #if defined(__HAS_BUILTIN_BOOL__) 00184 MSLRandomSource& MSLRandomSource::operator>>(char& x) 00185 { x = char(operator()()); 00186 return *this; 00187 } 00188 #endif 00189 00190 MSLRandomSource& MSLRandomSource::operator>>(int& x) 00191 { x = int(operator()()); 00192 return *this; 00193 } 00194 00195 MSLRandomSource& MSLRandomSource::operator>>(long& x) 00196 { x = long(operator()()); 00197 return *this; 00198 } 00199 00200 00201 00202 MSLRandomSource& MSLRandomSource::operator>>(unsigned char& x) 00203 { x = (unsigned char)(operator()()); 00204 return *this; 00205 } 00206 00207 00208 MSLRandomSource& MSLRandomSource::operator>>(unsigned int& x) 00209 { x = (unsigned int)(operator()()); 00210 return *this; 00211 } 00212 00213 MSLRandomSource& MSLRandomSource::operator>>(unsigned long& x) 00214 { x = (unsigned long)(operator()()); 00215 return *this; 00216 } 00217 00218 00219 00220 MSLRandomSource& MSLRandomSource::operator>>(float& x) 00221 { x = float(get_rand31())/RANDMAX; 00222 return *this; 00223 } 00224 00225 00226 00227 MSLRandomSource& MSLRandomSource::operator>>(double& x) 00228 { x = double(get_rand31())/RANDMAX; 00229 return *this; 00230 } 00231 00232