7#include <Common/primitive_type.h>
14#define PH_MATH_PCG64_FORCE_EMULATED_UINT128 0
16#if !defined(__SIZEOF_INT128__) || PH_MATH_PCG64_FORCE_EMULATED_UINT128
17#define PH_MATH_PCG64_EMULATED_UINT128 1
19#define PH_MATH_PCG64_EMULATED_UINT128 0
42#if PH_MATH_PCG64_EMULATED_UINT128
55#if PH_MATH_PCG64_EMULATED_UINT128
59 : m_128((__uint128_t(high64) << 64) + low64)
65#if PH_MATH_PCG64_EMULATED_UINT128
68 return static_cast<uint64
>(m_128 >> 64);
74#if PH_MATH_PCG64_EMULATED_UINT128
77 return static_cast<uint64
>(m_128);
84#if PH_MATH_PCG64_EMULATED_UINT128
85 result.m_low64 = m_low64 + rhs.m_low64;
86 result.m_high64 = m_high64 + rhs.m_high64 + (result.m_low64 < m_low64);
88 result.m_128 = m_128 + rhs.m_128;
96#if PH_MATH_PCG64_EMULATED_UINT128
102 result.m_high64 += (m_high64 * rhs.m_low64) + (m_low64 * rhs.m_high64);
104 result.m_128 = m_128 * rhs.m_128;
147 Pcg64DXSM(uint64 initialSequenceHigh64, uint64 initialSequenceLow64);
158 uint64 initialSequenceHigh64, uint64 initialSequenceLow64,
159 uint64 initialStateHigh64, uint64 initialStateLow64);
167 uint64 generateUInt64();
169 inline static constexpr auto DEFAULT_STATE =
UInt128(0x979C9A98D8462005ull, 0x7D3E9CB6CFE0549Bull);
170 inline static constexpr auto DEFAULT_STREAM_ID =
UInt128(0x5851F42D4C957F2Dull, 0x14057B7EF767814Full);
173 inline static constexpr auto CHEAP_MULTIPLIER_64 = 0xDA942042E4DD58B5ull;
175 UInt128 m_state = DEFAULT_STATE;
178 UInt128 m_increment = DEFAULT_STREAM_ID;
183 initialSequenceHigh64, initialSequenceLow64,
188 const uint64 initialSequenceHigh64,
const uint64 initialSequenceLow64,
189 const uint64 initialStateHigh64,
const uint64 initialStateLow64)
195 uint64 incrementHigh64 = initialSequenceHigh64 << 1u;
196 incrementHigh64 |= initialSequenceLow64 >> 63u;
197 uint64 incrementLow64 = (initialSequenceLow64 << 1u) | 1u;
198 m_increment =
UInt128(incrementHigh64, incrementLow64);
201 m_state = m_state +
UInt128(initialStateHigh64, initialStateLow64);
207 return generateUInt64();
222 constexpr auto ZERO =
UInt128(0, 0);
223 constexpr auto ONE =
UInt128(0, 1);
225 auto curMult =
UInt128(0, CHEAP_MULTIPLIER_64);
226 auto curPlus = m_increment;
229 uint64 delta = distance;
234 accMult = accMult * curMult;
235 accPlus = accPlus * curMult + curPlus;
237 curPlus = (curMult + ONE) * curPlus;
238 curMult = curMult * curMult;
241 m_state = accMult * m_state + accPlus;
244inline uint64 Pcg64DXSM::generateUInt64()
247 const UInt128 oldState = m_state;
248 m_state = oldState * UInt128(0, CHEAP_MULTIPLIER_64) + m_increment;
252 uint64 lo = oldState.getLow64();
255 hi *= CHEAP_MULTIPLIER_64;
PCG-64 DXSM generator. This is the pcg_engines::cm_setseq_dxsm_128_64 generator in O'Neill's original...
Definition Pcg64DXSM.h:143
uint64 impl_generate()
Definition Pcg64DXSM.h:205
void impl_jumpAhead(uint64 distance)
Definition Pcg64DXSM.h:210
PH_DEFINE_INLINE_RULE_OF_5_MEMBERS(Pcg64DXSM)
Pcg64DXSM(uint64 initialSequenceHigh64, uint64 initialSequenceLow64)
Definition Pcg64DXSM.h:181
Definition Pcg64DXSM.h:30
Pcg64UInt128 operator*(const Pcg64UInt128 &rhs) const
Definition Pcg64DXSM.h:93
constexpr Pcg64UInt128()
Definition Pcg64DXSM.h:50
Pcg64UInt128 operator+(const Pcg64UInt128 &rhs) const
Definition Pcg64DXSM.h:81
uint64 getLow64() const
Definition Pcg64DXSM.h:72
uint64 getHigh64() const
Definition Pcg64DXSM.h:63
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
uint64 moremur_bit_mix_64(uint64 v)
A MurmurHash3-style bit mixer that outperforms the original by quite some margin. 64-bit version.
Definition hash.ipp:104
void uint64_mul(const uint64 lhs, const uint64 rhs, uint64 &out_high64, uint64 &out_low64)
Multiply two unsigined 64-bit numbers and get a 128-bit result.
Definition math.h:695