From 86b855bda35391c0d29e0ee7f4ddeacb68158cf0 Mon Sep 17 00:00:00 2001 From: Avril Date: Sat, 6 Nov 2021 20:08:30 +0000 Subject: [PATCH] Added seeding interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added splitmix64 seed generator. Added splitmix64 random generator. Fortune for rngxx's current commit: Future small blessing − 末小吉 --- Makefile | 2 +- include/rngxx/crand.h | 3 ++- include/rngxx/internal/seed.h | 22 ++++++++++++++-------- include/rngxx/sm64.h | 22 ++++++++++++++++++++++ src/seed.cpp | 30 +++++++++++++++++++++++++----- 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 include/rngxx/sm64.h diff --git a/Makefile b/Makefile index 3c1c84c..909166e 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ PROJECT=rngxx AUTHOR=Avril (Flanchan) VERSION_MAJOR=1 -VERSION_MINOR=0 +VERSION_MINOR=1 VERSION=$(VERSION_MAJOR).$(VERSION_MINOR) ifeq ($(PREFIX),) diff --git a/include/rngxx/crand.h b/include/rngxx/crand.h index 701b5fa..9643e91 100644 --- a/include/rngxx/crand.h +++ b/include/rngxx/crand.h @@ -1,10 +1,11 @@ #pragma once -#include "internal/common.h" #include #include "internal/mem.h" +#include "internal/common.h" + namespace rng { struct crand final : public Random diff --git a/include/rngxx/internal/seed.h b/include/rngxx/internal/seed.h index 24a6711..76eca75 100644 --- a/include/rngxx/internal/seed.h +++ b/include/rngxx/internal/seed.h @@ -14,18 +14,24 @@ namespace rng namespace seed { - typedef u64 sm128r[2]; - struct sm128 { - sm128r m_raw; - }; - - struct splitmix64 : public virtual seed_gen + struct splitmix64 : public virtual seed_gen { + inline splitmix64(const splitmix64&) = default; + explicit inline splitmix64(seed_gen& from) : m_state(from.generate_seed()){} 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: - sm128r m_state; + u64 m_state; }; } } diff --git a/include/rngxx/sm64.h b/include/rngxx/sm64.h new file mode 100644 index 0000000..b70a12c --- /dev/null +++ b/include/rngxx/sm64.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#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& 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; + }; +} diff --git a/src/seed.cpp b/src/seed.cpp index 21537cf..b5c5564 100644 --- a/src/seed.cpp +++ b/src/seed.cpp @@ -1,13 +1,33 @@ +#include +#include + #include -extern "C" { - // TODO: XXX: how to return a god damn array without typedef ffs???? - extern u64 (*sm64_compute[2])(u64, u64); +#include + +#include + +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 { - 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; + } }