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