2020-05-25 13:19:25 +00:00
|
|
|
#include "prng.h"
|
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
// From https://en.wikipedia.org/w/index.php?title=Permuted_congruential_generator&oldid=901497400#Example_code.
|
|
|
|
//
|
|
|
|
// > The generator recommended for most users is PCG-XSH-RR with 64-bit state
|
|
|
|
// > and 32-bit output.
|
2020-05-25 13:19:25 +00:00
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
#define NAME "pcg-xsh-rr"
|
2020-05-25 13:19:25 +00:00
|
|
|
|
|
|
|
CPrng::CPrng() :
|
|
|
|
m_Seeded(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char *CPrng::Description() const
|
|
|
|
{
|
|
|
|
if(!m_Seeded)
|
|
|
|
{
|
|
|
|
return NAME ":unseeded";
|
|
|
|
}
|
|
|
|
return m_aDescription;
|
|
|
|
}
|
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
static unsigned int RotateRight32(unsigned int x, int Shift)
|
2020-05-25 13:19:25 +00:00
|
|
|
{
|
2020-05-26 08:59:49 +00:00
|
|
|
return (x >> Shift) | (x << (-Shift & 31));
|
|
|
|
}
|
2020-05-25 13:19:25 +00:00
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
void CPrng::Seed(uint64 aSeed[2])
|
|
|
|
{
|
2020-05-25 13:19:25 +00:00
|
|
|
m_Seeded = true;
|
2020-05-26 08:59:49 +00:00
|
|
|
str_format(m_aDescription, sizeof(m_aDescription), "%s:%016llx:%016llx", NAME, aSeed[0], aSeed[1]);
|
2020-05-25 13:19:25 +00:00
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
m_Increment = (aSeed[1] << 1) | 1;
|
|
|
|
m_State = aSeed[0] + m_Increment;
|
|
|
|
RandomBits();
|
2020-05-25 13:19:25 +00:00
|
|
|
}
|
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
unsigned int CPrng::RandomBits()
|
2020-05-25 13:19:25 +00:00
|
|
|
{
|
|
|
|
dbg_assert(m_Seeded, "prng needs to be seeded before it can generate random numbers");
|
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
uint64 x = m_State;
|
|
|
|
unsigned int Count = x >> 59;
|
2020-05-25 13:19:25 +00:00
|
|
|
|
2020-05-26 08:59:49 +00:00
|
|
|
static const uint64 MULTIPLIER = 6364136223846793005u;
|
|
|
|
m_State = x * MULTIPLIER + m_Increment;
|
|
|
|
x ^= x >> 18;
|
|
|
|
return RotateRight32(x >> 27, Count);
|
2020-05-25 13:19:25 +00:00
|
|
|
}
|