1
0

Migrated random generators to std::random

This commit is contained in:
Tiger Wang
2014-10-19 14:10:18 +01:00
parent cc600de51f
commit aa19a3afb0
16 changed files with 102 additions and 556 deletions

View File

@@ -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);
}