Added seeding interface.

Added splitmix64 seed generator.

Added splitmix64 random generator.

Fortune for rngxx's current commit: Future small blessing − 末小吉
master
Avril 3 years ago
parent d9e34e7e70
commit 86b855bda3
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -4,7 +4,7 @@ PROJECT=rngxx
AUTHOR=Avril (Flanchan) <flanchan@cumallover.me> AUTHOR=Avril (Flanchan) <flanchan@cumallover.me>
VERSION_MAJOR=1 VERSION_MAJOR=1
VERSION_MINOR=0 VERSION_MINOR=1
VERSION=$(VERSION_MAJOR).$(VERSION_MINOR) VERSION=$(VERSION_MAJOR).$(VERSION_MINOR)
ifeq ($(PREFIX),) ifeq ($(PREFIX),)

@ -1,10 +1,11 @@
#pragma once #pragma once
#include "internal/common.h"
#include <rngxx.hpp> #include <rngxx.hpp>
#include "internal/mem.h" #include "internal/mem.h"
#include "internal/common.h"
namespace rng namespace rng
{ {
struct crand final : public Random struct crand final : public Random

@ -14,18 +14,24 @@ namespace rng
namespace seed namespace seed
{ {
typedef u64 sm128r[2]; struct splitmix64 : public virtual seed_gen<u64>
struct sm128 {
sm128r m_raw;
};
struct splitmix64 : public virtual seed_gen<sm128>
{ {
inline splitmix64(const splitmix64&) = default;
explicit inline splitmix64(seed_gen<u64>& from) : m_state(from.generate_seed()){}
splitmix64(u64 i); splitmix64(u64 i);
sm128 generate_seed() override; u64 generate_seed() override;
f64 generate_f64();
inline virtual ~splitmix64() override{}
static u64 oneshot(u64& state);
inline static u64 oneshot(const u64& state) { u64 s = state; return oneshot(s); }
static f64 oneshotf(u64& state);
inline static f64 oneshotf(const u64& state) { u64 s = state; return oneshotf(s); }
static splitmix64 random();
private: private:
sm128r m_state; u64 m_state;
}; };
} }
} }

@ -0,0 +1,22 @@
#pragma once
#include <rngxx.hpp>
#include "internal/seed.h"
namespace rng
{
struct sm64 final : public Random
{
inline sm64() : m_generator(seed::splitmix64::random()){}
inline sm64(const seed::splitmix64& g) : m_generator(g){}
explicit inline sm64(seed_gen<u64>& generator) : m_generator(generator){}
inline sm64(u64 seed) : Random(), m_generator(seed){}
RNG_OVERRIDE(inline u64, next_u64, ()) { return m_generator.generate_seed(); }
protected:
inline f64 _sample() override { return m_generator.generate_f64(); }
private:
seed::splitmix64 m_generator;
};
}

@ -1,13 +1,33 @@
#include <cmath>
#include <ctime>
#include <seed.h> #include <seed.h>
extern "C" { #include <common.h>
// TODO: XXX: how to return a god damn array without typedef ffs????
extern u64 (*sm64_compute[2])(u64, u64); #include <rngxx/sm64.h>
static u64 _sm64_next(u64& x)
{
u64 z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
} }
namespace rng::seed namespace rng::seed
{ {
splitmix64::splitmix64(u64 u) : m_state(sm64_compute(u, 0)){} splitmix64::splitmix64(u64 u) : m_state(u){}
u64 splitmix64::generate_seed() { return _sm64_next(m_state); }
f64 splitmix64::generate_f64() { return generate_seed() / pow(2.0, 64); }
u64 splitmix64::oneshot(u64& state) { return _sm64_next(state); }
f64 splitmix64::oneshotf(u64& state) { return _sm64_next(state) / pow(2.0, 64); }
sm128 splitmix64::generate_seed() { return sm128 { m_state = sm64_compute(m_state[0], m_state[1]) }; } splitmix64 splitmix64::random()
{
splitmix64 r (oneshot(time(NULL)));
return r;
}
} }

Loading…
Cancel
Save