00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdafx.h"
00027 #include "rng.h"
00028
00029
00030 #define M 397
00031 #define MATRIX_A 0x9908b0dfUL
00032 #define UPPER_MASK 0x80000000UL
00033 #define LOWER_MASK 0x7fffffffUL
00034
00035 void RNG::Seed(uint32_t seed) const {
00036 mt[0]= seed & 0xffffffffUL;
00037 for (mti=1; mti<N; mti++) {
00038 mt[mti] =
00039 (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00040
00041
00042
00043
00044 mt[mti] &= 0xffffffffUL;
00045
00046 }
00047 }
00048
00049
00050
00051 float RNG::RandomFloat() const
00052 {
00053 PBRT_RNG_STARTED_RANDOM_FLOAT();
00054 float v = (RandomUInt() & 0xffffff) / float(1 << 24);
00055 PBRT_RNG_FINISHED_RANDOM_FLOAT();
00056 return v;
00057 }
00058
00059
00060
00061
00062 unsigned long RNG::RandomUInt() const
00063 {
00064 unsigned long y;
00065 static unsigned long mag01[2]={0x0UL, MATRIX_A};
00066
00067
00068 if (mti >= N) {
00069 PBRT_RNG_STARTED_TABLEGEN();
00070 int kk;
00071
00072 if (mti == N+1)
00073 Seed(5489UL);
00074
00075 for (kk=0;kk<N-M;kk++) {
00076 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00077 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
00078 }
00079 for (;kk<N-1;kk++) {
00080 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00081 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
00082 }
00083 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00084 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
00085
00086 mti = 0;
00087 PBRT_RNG_FINISHED_TABLEGEN();
00088 }
00089
00090 y = mt[mti++];
00091
00092
00093 y ^= (y >> 11);
00094 y ^= (y << 7) & 0x9d2c5680UL;
00095 y ^= (y << 15) & 0xefc60000UL;
00096 y ^= (y >> 18);
00097
00098 return y;
00099 }
00100
00101