random using xoshiro256+

This commit is contained in:
sillysagiri 2024-11-06 16:10:50 +07:00
parent 28b4575bbc
commit f12e61b1b5
2 changed files with 38 additions and 76 deletions

View File

@ -1,66 +1,45 @@
#include <chrono>
#include <cmath>
#include "utils/Random.hpp" #include "utils/Random.hpp"
panda::Random::Random(uint32_t _w, uint32_t _z) { static inline uint64_t splitmix64(uint64_t &x) {
m_w = _w; uint64_t z = (x += 0x9e3779b97f4a7c15);
m_z = _z; z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
} }
void panda::Random::setSeed(uint32_t w) { static inline uint64_t rotl(const uint64_t x, int k) {
if (w != 0) m_w = w; return (x << k) | (x >> (64 - k));
} }
void panda::Random::setSeed(uint32_t w, uint32_t z) { panda::Random::Random(uint64_t seed) {
if (w != 0) m_w = w; for(int i=0; i<4; i++) s[i] = splitmix64(seed);
if (z != 0) m_z = z;
} }
void panda::Random::setSeedFromTime() { void panda::Random::SetSeed(uint64_t seed) {
m_w = std::chrono::system_clock::now().time_since_epoch().count(); for(int i=0; i<4; i++) s[i] = splitmix64(seed);
} }
uint32_t panda::Random::MWC() { uint64_t panda::Random::Next() {
m_z = 36969 * (m_z & 65535) + (m_z >> 16); const uint64_t result = s[0] + s[3];
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; const uint64_t t = s[1] << 17;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = rotl(s[3], 45);
return result;
} }
float panda::Random::UNI() { double panda::Random::Next_UNI() {
return MWC() * inv_uni; return (Next() >> 11) * 0x1.0p-53;
} }
float panda::Random::range(float min, float max) { double panda::Random::Range(double min, double max) {
return min + (max-min) * UNI(); return min + (max-min) * Next_UNI();
}
float panda::Random::rangeEx(float min, float max, float lamda) {
const float u = UNI();
return min + (max-min) * std::pow(u, lamda);
}
float panda::Random::xorshift_uni(uint32_t x) {
return xorshift(x) * inv_uni;
}
float panda::Random::xorshift64_uni(uint64_t x) {
return xorshift64(x) * inv_uni64;
}
uint32_t panda::Random::xorshift(uint32_t x) {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return x;
}
uint64_t panda::Random::xorshift64(uint64_t x) {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
} }

View File

@ -5,31 +5,14 @@ namespace panda
{ {
class Random { class Random {
public: public:
static Random& getInstance() Random(uint64_t seed = 521288629);
{ void SetSeed(uint64_t seed);
static Random instance;
return instance;
}
Random(uint32_t _w = 521288629, uint32_t _z = 362436069); uint64_t Next();
void setSeed(uint32_t w); double Next_UNI();
void setSeed(uint32_t w, uint32_t z); double Range(double min, double max);
void setSeedFromTime();
uint32_t MWC();
float UNI();
float range(float min, float max);
float rangeEx(float min, float max, float lamda);
float xorshift_uni(uint32_t x);
float xorshift64_uni(uint64_t x);
uint32_t xorshift(uint32_t x);
uint64_t xorshift64(uint64_t x);
private: private:
uint32_t m_w; uint64_t s[4];
uint32_t m_z;
float inv_uni = 2.3283064e-10;
float inv_uni64 = 5.4210109e-20;
}; };
} }