Skip to content

Instantly share code, notes, and snippets.

@geraintluff
Last active April 9, 2026 18:02
Show Gist options
  • Select an option

  • Save geraintluff/21813f9b650f6804c72c5d60c3e3989b to your computer and use it in GitHub Desktop.

Select an option

Save geraintluff/21813f9b650f6804c72c5d60c3e3989b to your computer and use it in GitHub Desktop.
32-bit PCG random numbers, in C++
// PCG-32 implementation: https://pcg-random.org/
// (c) 2026 Signalsmith Audio
// 0BSD Licence, or you can re-distribution with any license you like, just replace this line
#include <random>
struct Pcg32 {
uint64_t state;
static constexpr uint64_t multiply = 6364136223846793005ULL;
uint64_t add;
// This is the core of it, which gets the next 32-bit value
uint32_t u32() {
uint64_t prevState = state;
state = prevState*multiply + add;
auto xorShift = uint32_t(((prevState>>18)^prevState)>>27);
auto rotateBits = uint32_t(prevState>>59);
return (xorShift>>rotateBits)|(xorShift<<((-rotateBits)&31));
}
// Everything below this point is just for convenience
Pcg32(uint64_t state, uint64_t add) : state(state), add(add|1) {}
Pcg32() : Pcg32(std::random_device{}) {}
template<class Uint32Source>
Pcg32(Uint32Source &&seed) {
state = uint64_t(seed());
state |= uint64_t(seed())<<32;
add = 1|uint64_t(seed());
add |= uint64_t(seed())<<32;
}
// Results as other number types
int32_t i32() {
return static_cast<int32_t>(u32());
}
// [0, x)
float uniform(float range) {
return u32()*(range/0x100000000);
}
// [-x, x)
float uniform2(float range) {
return i32()*(range/0x80000000);
}
// [low, high)
float uniform(float low, float high) {
return low + u32()*((high - low)/0x100000000);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment