Skip to content

Instantly share code, notes, and snippets.

@leduyquang753
Last active January 14, 2022 14:29
Show Gist options
  • Save leduyquang753/1b7a5a6ad2038243559fa0cefbeb23f7 to your computer and use it in GitHub Desktop.
Save leduyquang753/1b7a5a6ad2038243559fa0cefbeb23f7 to your computer and use it in GitHub Desktop.
"A small noncryptographic PRNG" in C++ as posted in burtleburtle.net.
#include <BurtleRNG.h>
BurtleRNG::BurtleRNG(const std::uint32_t &seed):
a(0xf1ea5eed), b(seed), c(seed), d(seed)
{
for (int i = 0; i != 20; i++) get();
}
std::uint32_t BurtleRNG::get() {
#define rotate(x, k) (((x)<<(k)) | ((x)>>(32-(k))))
const std::uint32_t e = a - rotate(b, 27);
a = b ^ rotate(c, 17);
b = c + d;
c = d + e;
d = e + a;
return d;
#undef rotate
}
std::uint32_t BurtleRNG::getInt(const std::uint32_t &bound) {
std::uint32_t r = get() & (1u<<31)-1;
const std::uint32_t m = bound-1;
if ((bound & m) == 0) {
r = bound*static_cast<std::uint64_t>(r) >> 31;
} else {
for (
int u = r;
u - (r = u%bound) + m < 0;
u = get() & (1u<<31)-1
);
}
return r;
}
double BurtleRNG::getDouble() {
return (
(static_cast<std::uint64_t>(get() & (1u<<26)-1) << 27)
+ (get() & (1u<<27)-1)
) * 0x1.0p-53;
}
float BurtleRNG::getFloat() {
return (get() & (1u<<24)-1) / static_cast<float>(1u<<24);
}
// "A small noncryptographic PRNG" as originally posted in
// https://burtleburtle.net/bob/rand/smallprng.html
#pragma once
#include <cstdint>
class BurtleRNG {
public:
std::uint32_t a = 0, b = 0, c = 0, d = 0;
BurtleRNG(const std::uint32_t &seed);
std::uint32_t get();
std::uint32_t getInt(const std::uint32_t &bound);
double getDouble();
float getFloat();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment