Migrated random generators to std::random
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user