1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: math_TinyMt.h 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 47802 $ 14 *---------------------------------------------------------------------------*/ 15 16 /* Please see man pages for details 17 18 19 20 */ 21 22 #ifndef NN_MATH_MATH_TINY_MT_H_ 23 #define NN_MATH_MATH_TINY_MT_H_ 24 25 #include <nn/types.h> 26 27 namespace nn { namespace math { 28 29 /* ------------------------------------------------------------------------ 30 Class definitions 31 ------------------------------------------------------------------------ */ 32 33 //---------------------------------------------------------------------- 34 // 35 // 36 // 37 // 38 // 39 // 40 // 41 // 42 // 43 // 44 // 45 // 46 // 47 // 48 // 49 //---------------------------------------------------------------------- 50 class TinyMt 51 { 52 private: 53 static const int PARAMETER_N = 4; 54 static const bit32 PARAMETER_MAT1 = 0x8f7011ee; 55 static const bit32 PARAMETER_MAT2 = 0xfc78ff1f; 56 static const bit32 PARAMETER_TMAT = 0x3793fdff; 57 58 static const int MIN_LOOP = 8; 59 static const int NUM_SKIP = 8; 60 61 static const bit32 BIT31_MASK = ~0u >> 1; 62 63 public: 64 //---------------------------------------------------------------------- 65 // 66 //---------------------------------------------------------------------- 67 struct State 68 { 69 //---------------------------------------------------------------------- 70 // 71 //---------------------------------------------------------------------- 72 bit32 state[PARAMETER_N]; 73 }; 74 75 private: 76 bit32 m_State[PARAMETER_N]; 77 78 public: 79 80 // 81 // 82 83 //---------------------------------------------------------------------- 84 // 85 // 86 // 87 // 88 // 89 //---------------------------------------------------------------------- 90 void Initialize(); 91 92 //---------------------------------------------------------------------- 93 // 94 // 95 // 96 // 97 // 98 //---------------------------------------------------------------------- 99 void Initialize(bit32 seed); 100 101 //---------------------------------------------------------------------- 102 // 103 // 104 // 105 // 106 // 107 // 108 //---------------------------------------------------------------------- 109 void Initialize(const bit32* pSeed, int numSeed); 110 111 //---------------------------------------------------------------------- 112 // 113 //---------------------------------------------------------------------- Finalize()114 void Finalize(){} 115 116 // 117 118 // 119 // 120 121 //---------------------------------------------------------------------- 122 // 123 // 124 // 125 // 126 // 127 // 128 // 129 // 130 // 131 // 132 // 133 //---------------------------------------------------------------------- 134 void SaveState(TinyMt::State* pStateBuffer); 135 136 //---------------------------------------------------------------------- 137 // 138 // 139 // 140 // 141 // 142 // 143 // 144 // 145 //---------------------------------------------------------------------- 146 void RestoreState(const TinyMt::State* pStateBuffer); 147 148 // 149 150 // 151 // 152 153 //---------------------------------------------------------------------- 154 // 155 // 156 // 157 // 158 // 159 //---------------------------------------------------------------------- 160 u32 GenerateRandomU32(); 161 162 //---------------------------------------------------------------------- 163 // 164 // 165 // 166 // 167 // 168 //---------------------------------------------------------------------- 169 u64 GenerateRandomU64(); 170 171 //---------------------------------------------------------------------- 172 // 173 // 174 // 175 //---------------------------------------------------------------------- 176 f32 GenerateRandomF32(); 177 178 //---------------------------------------------------------------------- 179 // 180 // 181 // 182 //---------------------------------------------------------------------- 183 f64 GenerateRandomF64(); 184 185 //---------------------------------------------------------------------- 186 // 187 // 188 // 189 // 190 // 191 // 192 // 193 // 194 // 195 // 196 // 197 // 198 // 199 // 200 // 201 // 202 // 203 // 204 // 205 // 206 // 207 // 208 //---------------------------------------------------------------------- 209 u32 GenerateRandomN(u16 max); 210 211 //---------------------------------------------------------------------- 212 // 213 // 214 // 215 // 216 // 217 // 218 // 219 //---------------------------------------------------------------------- 220 void GenerateRandomBytes(void* p, size_t size); 221 222 // 223 224 private: GenerateRandomU24()225 u32 GenerateRandomU24() 226 { 227 return GenerateRandomU32() >> 8; 228 } 229 230 void FinalizeInitialization(); 231 232 static void GenerateInitialValuePlus(bit32* p, int d, bit32 k); 233 static void GenerateInitialValueXor(bit32* p, int d); 234 }; 235 236 237 238 /* ------------------------------------------------------------------------ 239 Inline member function definitions 240 ------------------------------------------------------------------------ */ 241 GenerateRandomU64()242 inline u64 TinyMt::GenerateRandomU64() 243 { 244 const u32 lo = GenerateRandomU32(); 245 const u32 hi = GenerateRandomU32(); 246 return (static_cast<u64>(hi) << 32) | lo; 247 } 248 GenerateRandomF32()249 inline f32 TinyMt::GenerateRandomF32() 250 { 251 return GenerateRandomU24() * (1.0f / (1ull << 24)); 252 } 253 GenerateRandomF64()254 inline f64 TinyMt::GenerateRandomF64() 255 { 256 static const int RESOLUTION = 53; 257 static const int U32_BITS = 32; 258 static const int A_SHIFT = (2 * U32_BITS - RESOLUTION) / 2; 259 static const int B_SHIFT = (2 * U32_BITS - RESOLUTION) - A_SHIFT; 260 //static const int A_BITS = U32_BITS - A_SHIFT; 261 static const int B_BITS = U32_BITS - B_SHIFT; 262 263 u32 a = (GenerateRandomU32() >> A_SHIFT); 264 u32 b = (GenerateRandomU32() >> B_SHIFT); 265 266 return (1.0 * a * (1u << B_BITS) + b) * (1.0 / (1ull << RESOLUTION)); 267 } 268 GenerateRandomN(u16 max)269 inline u32 TinyMt::GenerateRandomN(u16 max) 270 { 271 return static_cast<u32>((static_cast<u64>(GenerateRandomU32()) * max) >> 32); 272 } 273 274 275 276 }} 277 278 279 /* NN_MATH_MATH_TINY_MT_H_ */ 280 #endif 281