diff options
Diffstat (limited to 'src/FastRandom.cpp')
-rw-r--r-- | src/FastRandom.cpp | 116 |
1 files changed, 62 insertions, 54 deletions
diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp index 42bf5f3f9..515dc25ea 100644 --- a/src/FastRandom.cpp +++ b/src/FastRandom.cpp @@ -4,13 +4,15 @@ // Implements the cFastRandom class representing a fast random number generator #include "Globals.h" -#include <time.h> #include "FastRandom.h" +//////////////////////////////////////////////////////////////////////////////// +// cFastRandom: + #if 0 && defined(_DEBUG) // Self-test // Both ints and floats are quick-tested to see if the random is calculated correctly, checking the range in ASSERTs, @@ -83,16 +85,8 @@ public: - -int cFastRandom::m_SeedCounter = 0; - - - - - cFastRandom::cFastRandom(void) : - m_Seed(m_SeedCounter++), - m_Counter(0) + m_LinearRand(static_cast<unsigned>(std::chrono::system_clock::now().time_since_epoch().count())) { } @@ -102,82 +96,96 @@ cFastRandom::cFastRandom(void) : int cFastRandom::NextInt(int a_Range) { - ASSERT(a_Range <= 1000000); // The random is not sufficiently linearly distributed with bigger ranges - ASSERT(a_Range > 0); - - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = a_Range + Counter * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - return ((n / 11) % a_Range); + std::uniform_int_distribution<> distribution(0, a_Range - 1); + return distribution(m_LinearRand); } + int cFastRandom::NextInt(int a_Range, int a_Salt) { - ASSERT(a_Range <= 1000000); // The random is not sufficiently linearly distributed with bigger ranges - ASSERT(a_Range > 0); - - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = a_Range + Counter * 57 + m_Seed * 57 * 57 + a_Salt * 57 * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - return ((n / 11) % a_Range); + m_LinearRand.seed(a_Salt); + std::uniform_int_distribution<> distribution(0, a_Range - 1); + return distribution(m_LinearRand); } + float cFastRandom::NextFloat(float a_Range) { - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = (int)a_Range + Counter * 57 + m_Seed * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - - // Convert the integer into float with the specified range: - return (((float)n / (float)0x7fffffff) * a_Range); + std::uniform_real_distribution<float> distribution(0, a_Range); + return distribution(m_LinearRand); } + float cFastRandom::NextFloat(float a_Range, int a_Salt) { - // Make the m_Counter operations as minimal as possible, to emulate atomicity - int Counter = m_Counter++; - - // Use a_Range, a_Salt, m_Counter and m_Seed as inputs to the pseudorandom function: - int n = (int)a_Range + Counter * 57 + m_Seed * 57 * 57 + a_Salt * 57 * 57 * 57; - n = (n << 13) ^ n; - n = ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff); - - // Convert the integer into float with the specified range: - return (((float)n / (float)0x7fffffff) * a_Range); + m_LinearRand.seed(a_Salt); + std::uniform_real_distribution<float> distribution(0, a_Range); + return distribution(m_LinearRand); } + int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End) { - cFastRandom Random; - return Random.NextInt(a_End - a_Begin + 1) + a_Begin; + std::uniform_int_distribution<> distribution(a_Begin, a_End); + return distribution(m_LinearRand); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// MTRand: + +MTRand::MTRand() : + m_MersenneRand(static_cast<unsigned>(std::chrono::system_clock::now().time_since_epoch().count())) +{ +} + + + + + +int MTRand::randInt(int a_Range) +{ + std::uniform_int_distribution<> distribution(0, a_Range); + return distribution(m_MersenneRand); +} + + + + + +int MTRand::randInt() +{ + std::uniform_int_distribution<> distribution(0, std::numeric_limits<int>::max()); + return distribution(m_MersenneRand); +} + + + + + +double MTRand::rand(double a_Range) +{ + std::uniform_real_distribution<> distribution(0, a_Range); + return distribution(m_MersenneRand); } |