libhatchet
Loading...
Searching...
No Matches
hxrandom.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
8
9#include "libhatchet.h"
10
11// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
12#if HX_USE_MACROS_WITH_MODULE
13#error Header does not provide macros alone.
14#endif
15
16HX_NS_BEGIN_
17
24class hxrandom {
25public:
28 hxconstexpr hxinline hxrandom(uint64_t stream_ = 1u) : m_state_(stream_) { }
29
31 hxattr_nodiscard hxinline hxconstexpr uint32_t operator()(void) { return this->u32(); }
32
39 template<typename T_> hxattr_nodiscard hxinline hxconstexpr T_ range(T_ base_, T_ size_) {
40 // Use double parameters if you need a bigger size. An emulated
41 // floating point multiply is faster and more stable than integer modulo.
42 hxassertmsg(static_cast<float>(size_) < float{0x01000000u},
43 "insufficient_precision %f", static_cast<float>(size_)); // 0x1p24f
44 return base_ + static_cast<T_>(static_cast<float>(size_) * this->f01());
45 }
46
48 hxattr_nodiscard hxinline hxconstexpr double range(double base_, double size_) {
49 // Use `uint64_t` parameters if you need a bigger size. An emulated
50 // floating point multiply is faster and more stable than integer modulo.
51 hxassertmsg(size_ < double{0x20000000000000ll},
52 "insufficient_precision %f", size_); // 0x1p53
53 return base_ + size_ * this->d01();
54 }
55
57 hxattr_nodiscard hxinline hxconstexpr int64_t range(int64_t base_, int64_t size_) {
58 hxassertmsg(size_ > 0, "zero_size");
59 return base_ + static_cast<int64_t>(this->u64() % static_cast<uint64_t>(size_));
60 }
61
63 hxattr_nodiscard hxinline hxconstexpr uint64_t range(uint64_t base_, uint64_t size_) {
64 hxassertmsg(size_ != 0u, "zero_size");
65 return base_ + this->u64() % size_;
66 }
67
72 hxinline void read(void* bytes_, hxsize_t count_) hxattr_nonnull(2) {
73 uint8_t* chars_ = static_cast<uint8_t*>(bytes_);
74 while (count_ >= 4) {
75 const uint32_t x_ = this->u32();
76 ::memcpy(chars_, &x_, 4u);
77 chars_ += 4;
78 count_ -= 4;
79 }
80 if (count_ > 0) {
81 const uint32_t x_ = this->u32();
82 ::memcpy(chars_, &x_, static_cast<size_t>(count_));
83 }
84 }
85
88 return static_cast<uint8_t>(this->u32());
89 }
90
93 return static_cast<uint16_t>(this->u32());
94 }
95
98 m_state_ = uint64_t{0x5851f42d4c957f2dull} * m_state_ + uint64_t{0x14057b7ef767814full};
99
100 // MODIFICATION: Use the 4 msb bits as a random 0..15 bit variable shift
101 // control. Ignores the low 13 bits because they are low quality.
102 // Returns 32 bits chosen at a random offset starting between the 13th
103 // and 28th bits. 4 bits shift control + 32 returned + up to 15 shifted
104 // off + 13 always discarded = 64 bits.
105 const uint32_t result_ = static_cast<uint32_t>(m_state_ >> ((m_state_ >> 60) + 13u));
106 return result_;
107 }
108
111 const uint64_t result_ = static_cast<uint64_t>(this->u32())
112 | (static_cast<uint64_t>(this->u32()) << 32);
113 return result_;
114 }
115
119 // Shift avoids rounding up.
120 return static_cast<float>(this->u32() >> 8) * (1.0f / 16777216.0f); // 0x1p-24f
121 }
122
126 // Shift avoids rounding up.
127 return static_cast<double>(this->u64() >> 11) * (1.0 / 9007199254740992.0); // 0x1p-53
128 }
129
130private:
131 uint64_t m_state_;
132};
133
134HX_NS_END_
constexpr uint32_t operator()(void)
Returns [0..2^32).
Definition hxrandom.hpp:31
constexpr uint64_t range(uint64_t base_, uint64_t size_)
uint64_t version. Zero size is undefined.
Definition hxrandom.hpp:63
constexpr hxrandom(uint64_t stream_=1u)
Constructor to initialize the random number generator.
Definition hxrandom.hpp:28
constexpr double d01(void)
Returns a double between [0..1).
Definition hxrandom.hpp:125
constexpr uint8_t u8(void)
Returns [0..2^8).
Definition hxrandom.hpp:87
constexpr uint64_t u64(void)
Returns [0..2^64).
Definition hxrandom.hpp:110
constexpr double range(double base_, double size_)
double version.
Definition hxrandom.hpp:48
constexpr uint16_t u16(void)
Returns [0..2^16).
Definition hxrandom.hpp:92
constexpr T range(T base_, T size_)
Returns a random number in the range [base..base+range).
Definition hxrandom.hpp:39
void read(void *bytes_, hxsize_t count_)
Reads a specified number of random bytes into the provided buffer.
Definition hxrandom.hpp:72
constexpr uint32_t u32(void)
Returns [0..2^32).
Definition hxrandom.hpp:97
constexpr float f01(void)
Returns a float between [0..1).
Definition hxrandom.hpp:118
constexpr int64_t range(int64_t base_, int64_t size_)
int64_t version. Negative or zero size is undefined.
Definition hxrandom.hpp:57
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:120
#define hxattr_nonnull(...)
hxattr_nonnull - Indicates that a function has args that should not be null.
Definition hxsettings.h:97
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:89
#define hxconstexpr
hxconstexpr - Enables C++23 compatable constexpr usage for functions as that has support for destruct...
Definition hxsettings.h:263
Provides core macros, memory management and feature detection.
#define hxassertmsg(x_,...)
hxassertmsg(bool x, ...) - Logs an error and terminates execution if x is false.
Definition libhatchet.h:101
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:209