tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
generate_canonical.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2022 Tobias Hienzsch
3
4#ifndef TETL_RANDOM_GENERATE_CANONICAL_HPP
5#define TETL_RANDOM_GENERATE_CANONICAL_HPP
6
7#include <etl/_algorithm/max.hpp>
8#include <etl/_algorithm/min.hpp>
9#include <etl/_cstddef/size_t.hpp>
10#include <etl/_cstdint/uint_t.hpp>
11#include <etl/_limits/numeric_limits.hpp>
12
13namespace etl {
14
15namespace detail {
16
17[[nodiscard]] constexpr auto generate_canonical_iterations(int bits, uint64_t gMin, uint64_t gMax) -> int
18{
19 if (bits == 0 || (gMax == numeric_limits<uint64_t>::max() && gMin == 0)) {
20 return 1;
21 }
22
23 auto const range = (gMax - gMin) + 1;
24 auto const target = ~uint64_t{0} >> (64 - bits);
25
26 auto product = uint64_t{1};
27 auto ceiling = int{0};
28
29 while (product <= target) {
30 ++ceiling;
31 if (product > numeric_limits<uint64_t>::max() / range) {
32 break;
33 }
34 product *= range;
35 }
36
37 return ceiling;
38}
39
40} // namespace detail
41
42/// \brief Generates a random floating point number in range [0,1).
43/// \ingroup random
44template <typename Real, size_t Bits, typename RNG>
45[[nodiscard]] constexpr auto generate_canonical(RNG& g) noexcept(noexcept(g())) -> Real
46{
47 constexpr auto digits = static_cast<size_t>(numeric_limits<Real>::digits);
48 constexpr auto minBits = static_cast<int>(digits < Bits ? digits : Bits);
49
50 auto const r = (static_cast<Real>(RNG::max()) - static_cast<Real>(RNG::min())) + Real{1};
51 auto const k = detail::generate_canonical_iterations(minBits, RNG::min(), RNG::max());
52
53 auto result = Real{0};
54 auto factor = Real{1};
55
56 for (int i = 0; i < k; ++i) {
57 result += (static_cast<Real>(g()) - RNG::min()) * factor;
58 factor *= r;
59 }
60
61 return result / factor;
62}
63
64} // namespace etl
65
66#endif // TETL_RANDOM_GENERATE_CANONICAL_HPP
constexpr auto generate_canonical(RNG &g) noexcept(noexcept(g())) -> Real
Generates a random floating point number in range [0,1).
Definition generate_canonical.hpp:45
Definition adjacent_find.hpp:9
static constexpr auto max() noexcept -> unsigned long
Definition numeric_limits.hpp:811
Definition numeric_limits.hpp:18