00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "randomc.h"
00025 
00026 
00027 void TRandomMersenne::RandomInit(uint32 seed) {
00028   
00029   mt[0]= seed;
00030   for (mti=1; mti < MERS_N; mti++) {
00031     mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);}
00032 
00033   
00034   union {double f; uint32 i[2];} convert;
00035   convert.f = 1.0;
00036   
00037   
00038   if (convert.i[1] == 0x3FF00000) Architecture = LITTLE_ENDIAN1;
00039   else if (convert.i[0] == 0x3FF00000) Architecture = BIG_ENDIAN1;
00040   else Architecture = NONIEEE;}
00041 
00042 uint32 TRandomMersenne::BRandom() {
00043   
00044   uint32 y;
00045 
00046   if (mti >= MERS_N) {
00047     
00048     const uint32 LOWER_MASK = (1LU << MERS_R) - 1;         
00049     const uint32 UPPER_MASK = 0xFFFFFFFF << MERS_R;        
00050     static const uint32 mag01[2] = {0, MERS_A};
00051 
00052     int kk;
00053     for (kk=0; kk < MERS_N-MERS_M; kk++) {
00054       y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
00055       mt[kk] = mt[kk+MERS_M] ^ (y >> 1) ^ mag01[y & 1];}
00056 
00057     for (; kk < MERS_N-1; kk++) {
00058       y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
00059       mt[kk] = mt[kk+(MERS_M-MERS_N)] ^ (y >> 1) ^ mag01[y & 1];}
00060 
00061     y = (mt[MERS_N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
00062     mt[MERS_N-1] = mt[MERS_M-1] ^ (y >> 1) ^ mag01[y & 1];
00063     mti = 0;}
00064 
00065   y = mt[mti++];
00066 
00067   
00068   y ^=  y >> MERS_U;
00069   y ^= (y << MERS_S) & MERS_B;
00070   y ^= (y << MERS_T) & MERS_C;
00071   y ^=  y >> MERS_L;
00072   return y;}
00073 
00074 
00075 
00076 double TRandomMersenne::Random() {
00077   
00078   union {double f; uint32 i[2];} convert;
00079   uint32 r = BRandom(); 
00080   
00081   
00082   
00083   
00084   
00085   
00086   
00087   
00088   
00089   switch (Architecture) {
00090   case LITTLE_ENDIAN1:
00091     convert.i[0] =  r << 20;
00092     convert.i[1] = (r >> 12) | 0x3FF00000;
00093     return convert.f - 1.0;
00094   case BIG_ENDIAN1:
00095     convert.i[1] =  r << 20;
00096     convert.i[0] = (r >> 12) | 0x3FF00000;
00097     return convert.f - 1.0;
00098   case NONIEEE: default:
00099   ;}
00100   
00101   
00102   return (double)r * (1./((double)(uint32)(-1L)+1.));}
00103