FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
rng.hpp
Go to the documentation of this file.
1#pragma once
2// xoshiro256** - the engine's only source of randomness; seeded from config and written to
3// the journal header so replays are bit-exact.
4#include "fastmm/core/config_macros.hpp"
5
6#include <cstdint>
7
8namespace fastmm {
9
10class Xoshiro256ss {
11 public:
12 explicit constexpr Xoshiro256ss(std::uint64_t seed = 0x9E3779B97F4A7C15ULL) noexcept {
13 reseed(seed);
14 }
15
16 constexpr void reseed(std::uint64_t seed) noexcept {
17 // splitmix64 expands the seed so that seed 0 does not produce the all-zero state.
18 std::uint64_t x = seed;
19 for (auto& w : s_) {
20 x += 0x9E3779B97F4A7C15ULL;
21 std::uint64_t z = x;
22 z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL;
23 z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL;
24 w = z ^ (z >> 31);
25 }
26 }
27
28 constexpr std::uint64_t next() noexcept {
29 const std::uint64_t result = rotl(s_[1] * 5, 7) * 9;
30 const std::uint64_t t = s_[1] << 17;
31 s_[2] ^= s_[0];
32 s_[3] ^= s_[1];
33 s_[1] ^= s_[2];
34 s_[0] ^= s_[3];
35 s_[2] ^= t;
36 s_[3] = rotl(s_[3], 45);
37 return result;
38 }
39 constexpr std::uint64_t operator()() noexcept { return next(); }
40
41 // Unbiased integer in [0, n) (Lemire's multiply-shift with rejection).
42 constexpr std::uint64_t uniform(std::uint64_t n) noexcept {
43 if (n == 0) return 0;
44 for (;;) {
45 const std::uint64_t x = next();
46 const Uint128 m = static_cast<Uint128>(x) * n;
47 const auto l = static_cast<std::uint64_t>(m);
48 if (l >= (0 - n) % n) return static_cast<std::uint64_t>(m >> 64);
49 }
50 }
51 // Integer in [lo, hi] inclusive.
52 constexpr std::int64_t between(std::int64_t lo, std::int64_t hi) noexcept {
53 return lo + static_cast<std::int64_t>(uniform(static_cast<std::uint64_t>(hi - lo) + 1));
54 }
55 // Double in [0, 1). Sim/backtest only (hot path is integer).
56 double uniform01() noexcept { return static_cast<double>(next() >> 11) * 0x1.0p-53; }
57
58 // std::uniform_random_bit_generator interface
59 using result_type = std::uint64_t;
60 static constexpr result_type min() noexcept { return 0; }
61 static constexpr result_type max() noexcept { return UINT64_MAX; }
63 private:
64 static constexpr std::uint64_t rotl(std::uint64_t x, int k) noexcept {
65 return (x << k) | (x >> (64 - k));
66 }
67 std::uint64_t s_[4] = {};
68};
69
70} // namespace fastmm
Definition rng.hpp:12
constexpr std::uint64_t operator()() noexcept
Definition rng.hpp:41
constexpr std::int64_t between(std::int64_t lo, std::int64_t hi) noexcept
Integer in [lo, hi] inclusive.
Definition rng.hpp:54
constexpr std::uint64_t uniform(std::uint64_t n) noexcept
Unbiased integer in [0, n) (Lemire's multiply-shift with rejection).
Definition rng.hpp:44
std::uint64_t result_type
std::uniform_random_bit_generator interface
Definition rng.hpp:61
double uniform01() noexcept
Double in [0, 1). Sim/backtest only (hot path is integer).
Definition rng.hpp:58
constexpr std::uint64_t next() noexcept
Definition rng.hpp:30
constexpr void reseed(std::uint64_t seed) noexcept
Definition rng.hpp:18
static constexpr result_type min() noexcept
Definition rng.hpp:62
static constexpr result_type max() noexcept
Definition rng.hpp:63
Definition strategy.hpp:16