diff options
author | Mattes D <github@xoft.cz> | 2014-12-07 15:01:36 +0100 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2014-12-07 15:01:36 +0100 |
commit | d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21 (patch) | |
tree | b0dbd8a8396ad22cf77cb4b367295d25ad3055a7 /src/FastRandom.cpp | |
parent | Reduced river height (diff) | |
parent | Merge remote-tracking branch 'origin/master' into c++11 (diff) | |
download | cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar.gz cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar.bz2 cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar.lz cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar.xz cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.tar.zst cuberite-d00ebd7ee700fcd7f30ea27d238ba1f0d56dfe21.zip |
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..cfafc7486 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); + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); + return m_IntDistribution(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); + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range - 1); + return m_IntDistribution(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); + m_FloatDistribution = std::uniform_real_distribution<float>(0, a_Range - 1); + return m_FloatDistribution(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); + m_FloatDistribution = std::uniform_real_distribution<float>(0, a_Range - 1); + return m_FloatDistribution(m_LinearRand); } + int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End) { - cFastRandom Random; - return Random.NextInt(a_End - a_Begin + 1) + a_Begin; + m_IntDistribution = std::uniform_int_distribution<>(a_Begin, a_End - 1); + return m_IntDistribution(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) +{ + m_IntDistribution = std::uniform_int_distribution<>(0, a_Range); + return m_IntDistribution(m_MersenneRand); +} + + + + + +int MTRand::randInt() +{ + m_IntDistribution = std::uniform_int_distribution<>(0, std::numeric_limits<int>::max()); + return m_IntDistribution(m_MersenneRand); +} + + + + + +double MTRand::rand(double a_Range) +{ + m_DoubleDistribution = std::uniform_real_distribution<>(0, a_Range); + return m_DoubleDistribution(m_MersenneRand); } |