Random number generation generally falls into a couple of categories: statistically-sound, cryptographically-secure generation, and 'I just want a random number' generation. The latter is the more common case, particularly with games, benchmarking and testing. It's not dreadfully important that someone can reverse-engineer the sequence, or that the sequence should have some layer of possible predictability; what's important is that it is, to the naive end user, unpredictable. As it turns out, PCG rand is a random number generator by Melissa O'Neill which has both the properties of being statistically sound in terms of it's distribution, and also blazingly fast - about 20% faster than the fastest xor-shift RNG, and about 700% faster than most implementations of C/C++'s rand().
It also avoids the trap which xor-shift RNG and most rand() implementations have, which is lower statistical variability in the lower bits. And since in most 'I just want a random number' scenarios, the range you're looking for a number within is typically small, the lower bits count. It still is not cryptographically secure (like Arc4Random), but neither is rand(). The speed is important - in microbenchmarking, having an RNG which is taking up 20% of the overall CPU time (as rand() was in some of mine) can disrupt and reduce the accuracy of measurements. And of course in games and other high-performance scenarios, you need a RNG which uses as little CPU time as possible.
My adaptation of Melissa O'Neill's algorithm greatly simplifies the interface so that it's more of a straight-forward replacement for scenarios where people would otherwise be using rand() or something similar, and adds noexcept specifiers. The original interface is more suited for those looking for in-depth random number generation with a lot more control and alternative approaches. I also enable support for C++98/03 code by substituting a 32-bit xor_shift128++ generator when those modes are detected - because PCG relies on specifiable cross-compilers types of at least 32 and 64-bit, which are difficult to guarantee in C++98/03.
There are two functions, plf::rand() and plf::srand(). Unlike rand() (which returns an int), plf::rand() returns an unsigned int, and like srand(), plf::srand() takes an unsigned int as it's argument. The function accesses and modifies internal state objects, which may cause data races with concurrent calls to rand or srand.
The original code for the Permuted Congruential generator is under an Apache license, which allows for derivative code to use alternative licenses. plf::rand is under a permissive zlib license. This means: Software is used on 'as-is' basis. It can be modified and used in commercial software. Authors are not liable for any damages arising from its use. The distribution of a modified version of the software is subject to the following restrictions:
Download here (6kb zip file) or
view the repository
The rand function library is a simple .h header file, to be included with a #include
command.
The zip includes a short benchmark comparing generation speed with rand(). This requires plf::nanotimer to run.
Return an unsigned 32-bit pseudo-random integer using pcg_rand in C++11 or higher compilers, xor_shift128++ in lower.
Seed the random number generator with an unsigned 32-bit integer.
Contact:
plf:: library and this page Copyright (c) 2022, Matthew Bentley