/** * @file RNG.h * @author OEOTYAN (https://github.com/OEOTYAN) * @brief Random Number Generator * * @copyright Created by OEOTYAN on 2022/09/03. * */ #pragma once #include "Global.h" #include namespace RNG { template inline T rand() { static pcg64 rng(pcg_extras::seed_seq_from{}); return static_cast(rng()); } template inline T rand(T min, T max) { static pcg64 rng(pcg_extras::seed_seq_from{}); return min + static_cast(rng(max - min + 1)); } template <> inline bool rand() { static pcg32 rng(pcg_extras::seed_seq_from{}); return static_cast(rng(2)); } template <> inline uint32_t rand() { static pcg32 rng(pcg_extras::seed_seq_from{}); return rng(); } template <> inline uint32_t rand(uint32_t min, uint32_t max) { static pcg32 rng(pcg_extras::seed_seq_from{}); return min + rng(max - min + 1); } template <> inline int32_t rand() { static pcg32 rng(pcg_extras::seed_seq_from{}); return static_cast(rng()); } template <> inline int32_t rand(int32_t min, int32_t max) { static pcg32 rng(pcg_extras::seed_seq_from{}); return (static_cast(min) + rng(static_cast(static_cast(max) - min + 1))); } template <> inline int64_t rand() { static pcg64 rng(pcg_extras::seed_seq_from{}); return static_cast(rng()); } template <> inline int64_t rand(int64_t min, int64_t max) { static pcg64 rng(pcg_extras::seed_seq_from{}); return min + static_cast(rng(static_cast(max - min + 1))); } template <> inline uint64_t rand() { static pcg64 rng(pcg_extras::seed_seq_from{}); return rng(); } template <> inline uint64_t rand(uint64_t min, uint64_t max) { static pcg64 rng(pcg_extras::seed_seq_from{}); return min + rng(max - min + 1); } template <> inline float rand() { union { uint32_t u; float f; } x; x.u = (rand() >> 9u) | 0x3f800000u; /* Trick from MTGP: generate an uniformly distributed single precision number in [1,2) and subtract 1. */ return x.f - 1.0f; } template <> inline float rand(float min, float max) { return min + rand() * (max - min); } template <> inline double rand() { union { uint64_t u; double f; } x; x.u = (rand() >> 12ull) | 0x3ff0000000000000ull; /* Trick from MTGP: generate an uniformly distributed single precision number in [1,2) and subtract 1. */ return x.f - 1.0; } template <> inline double rand(double min, double max) { return min + rand() * (max - min); } template inline T openIntervalRand(T min = 0, T max = 1) { return rand(std::nexttoward(min, LDBL_MAX), max); } template inline T closeIntervalRand(T min = 0, T max = 1) { return rand(min, std::nexttoward(max, LDBL_MAX)); } template inline T rightCloseIntervalRand(T min = 0, T max = 1) { return rand(std::nexttoward(min, LDBL_MAX), std::nexttoward(max, LDBL_MAX)); } template inline T leftCloseIntervalRand(T min = 0, T max = 1) { return rand(min, max); } } // namespace RNG