summaryrefslogtreecommitdiffstats
path: root/src/FastRandom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/FastRandom.cpp')
-rw-r--r--src/FastRandom.cpp116
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);
}