00001
00002
00070 #define DKUTIL_C_MT_RAND64_C
00071 #include "dkcMTRand64.h"
00072 #include <dkutil_c/dkc_misc.h>
00073
00074 #define NN dkcdMT_RAND64_NN
00075 #define MM 156
00076 #define MATRIX_A dkcmUINT64DEFINE(0xB5026F5AA96619E9)
00077 #define UM dkcmUINT64DEFINE(0xFFFFFFFF80000000)
00078 #define LM dkcmUINT64DEFINE(0x7FFFFFFF)
00079
00080 DKC_MT_RAND64 *WINAPI dkcAllocMTRand64(uint64 seed)
00081 {
00082 const uint32 alignMask = 15;
00083 char *tp = dkcAllocateFast_INL(sizeof(DKC_MT_RAND64) + alignMask);
00084 DKC_MT_RAND64 *p;
00085 if(NULL==tp) return NULL;
00086
00087 p = (DKC_MT_RAND64 *)(((int)tp + alignMask) & ~alignMask);
00088 p->mallocPtr = tp;
00089 dkcMTRand64SetNextFunction(p,dkcMTRand64Next_C);
00090 dkcMTRand64Init(p,seed);
00091 return p;
00092 }
00093
00094 int WINAPI dkcFreeMTRand64(DKC_MT_RAND64 **p)
00095 {
00096 dkcFreeFast_INL((void **)(&((*p)->mallocPtr)));
00097 return edk_SUCCEEDED;
00098 }
00099
00100 void WINAPI dkcMTRand64Init(DKC_MT_RAND64 *p,uint64 seed){
00101 int mti = p->index;
00102 uint64 *mt = p->state;
00103 p->state[0] = seed;
00104 for (mti=1; mti<NN; mti++)
00105 {
00106 mt[mti] = (dkcmUINT64DEFINE(6364136223846793005) * (mt[mti-1] ^ (mt[mti-1] >> 62)) + mti);
00107 }
00108 p->index = mti;
00109 }
00110
00111 void WINAPI dkcMTRand64InitByArray(DKC_MT_RAND64 *p,uint64 *init_key,uint64 key_length)
00112 {
00113 uint64 i, j, k;
00114 uint64 *mt = p->state;
00115 dkcMTRand64Init(p,dkcmUINT64DEFINE(19650218));
00116 i=1; j=0;
00117 k = (NN>key_length ? NN : key_length);
00118 for (; k; k--) {
00119 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * dkcmUINT64DEFINE(3935559000370003845)))
00120 + init_key[j] + j;
00121 i++; j++;
00122 if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
00123 if (j>=key_length) j=0;
00124 }
00125 for (k=NN-1; k; k--) {
00126 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * dkcmUINT64DEFINE(2862933555777941757)))
00127 - i;
00128 i++;
00129 if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
00130 }
00131
00132 mt[0] = dkcmUINT64DEFINE(1) << 63;
00133 }
00134
00135 DKC_INLINE void dkcMTRand64Next_C(DKC_MT_RAND64 *p){
00136 int i;
00137 int mti = p->index;
00138 uint64 *mt = p->state;
00139 uint64 x;
00140
00141
00142
00143
00144
00145
00146 static uint64 mag01[2]={dkcmUINT64DEFINE(0), MATRIX_A};
00147 for (i=0;i<NN-MM;i++) {
00148 x = (mt[i]&UM)|(mt[i+1]&LM);
00149 mt[i] = mt[i+MM] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00150 }
00151 for (;i<NN-1;i++) {
00152 x = (mt[i]&UM)|(mt[i+1]&LM);
00153 mt[i] = mt[i+(MM-NN)] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00154 }
00155 x = (mt[NN-1]&UM)|(mt[0]&LM);
00156 mt[NN-1] = mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&dkcmUINT64DEFINE(1))];
00157
00158 mti = 0;
00159
00160
00161 {
00162 uint64 *cache = p->output;
00163 for (i = 0; i < NN; i++) {
00164 register uint64 x;
00165 x = mt[i];
00166
00167 x ^= (x >> 29) & dkcmUINT64DEFINE(0x5555555555555555);
00168 x ^= (x << 17) & dkcmUINT64DEFINE(0x71D67FFFEDA60000);
00169 x ^= (x << 37) & dkcmUINT64DEFINE(0xFFF7EEE000000000);
00170 x ^= (x >> 43);
00171 cache[i] = x;
00172 }
00173 p->index = mti;
00174 }
00175 }
00176
00178 uint64 WINAPI dkcMTRand64Get(DKC_MT_RAND64 *p)
00179 {
00180 return dkcMTRand64Get_INL(p);
00181 }
00182