File indexing completed on 2025-01-30 09:31:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
0033 #define ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
0034
0035 #include <cassert>
0036 #include <cmath>
0037 #include <cstdint>
0038 #include <istream>
0039 #include <limits>
0040 #include <type_traits>
0041
0042 #include "absl/meta/type_traits.h"
0043 #include "absl/random/internal/fast_uniform_bits.h"
0044 #include "absl/random/internal/generate_real.h"
0045 #include "absl/random/internal/iostream_state_saver.h"
0046
0047 namespace absl {
0048 ABSL_NAMESPACE_BEGIN
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <typename RealType = double>
0064 class uniform_real_distribution {
0065 public:
0066 using result_type = RealType;
0067
0068 class param_type {
0069 public:
0070 using distribution_type = uniform_real_distribution;
0071
0072 explicit param_type(result_type lo = 0, result_type hi = 1)
0073 : lo_(lo), hi_(hi), range_(hi - lo) {
0074
0075 assert(lo <= hi);
0076
0077
0078
0079
0080
0081 assert(range_ <= (std::numeric_limits<result_type>::max)());
0082 }
0083
0084 result_type a() const { return lo_; }
0085 result_type b() const { return hi_; }
0086
0087 friend bool operator==(const param_type& a, const param_type& b) {
0088 return a.lo_ == b.lo_ && a.hi_ == b.hi_;
0089 }
0090
0091 friend bool operator!=(const param_type& a, const param_type& b) {
0092 return !(a == b);
0093 }
0094
0095 private:
0096 friend class uniform_real_distribution;
0097 result_type lo_, hi_, range_;
0098
0099 static_assert(std::is_floating_point<RealType>::value,
0100 "Class-template absl::uniform_real_distribution<> must be "
0101 "parameterized using a floating-point type.");
0102 };
0103
0104 uniform_real_distribution() : uniform_real_distribution(0) {}
0105
0106 explicit uniform_real_distribution(result_type lo, result_type hi = 1)
0107 : param_(lo, hi) {}
0108
0109 explicit uniform_real_distribution(const param_type& param) : param_(param) {}
0110
0111
0112
0113
0114
0115 void reset() {}
0116
0117 template <typename URBG>
0118 result_type operator()(URBG& gen) {
0119 return operator()(gen, param_);
0120 }
0121
0122 template <typename URBG>
0123 result_type operator()(URBG& gen,
0124 const param_type& p);
0125
0126 result_type a() const { return param_.a(); }
0127 result_type b() const { return param_.b(); }
0128
0129 param_type param() const { return param_; }
0130 void param(const param_type& params) { param_ = params; }
0131
0132 result_type(min)() const { return a(); }
0133 result_type(max)() const { return b(); }
0134
0135 friend bool operator==(const uniform_real_distribution& a,
0136 const uniform_real_distribution& b) {
0137 return a.param_ == b.param_;
0138 }
0139 friend bool operator!=(const uniform_real_distribution& a,
0140 const uniform_real_distribution& b) {
0141 return a.param_ != b.param_;
0142 }
0143
0144 private:
0145 param_type param_;
0146 random_internal::FastUniformBits<uint64_t> fast_u64_;
0147 };
0148
0149
0150
0151
0152 template <typename RealType>
0153 template <typename URBG>
0154 typename uniform_real_distribution<RealType>::result_type
0155 uniform_real_distribution<RealType>::operator()(
0156 URBG& gen, const param_type& p) {
0157 using random_internal::GeneratePositiveTag;
0158 using random_internal::GenerateRealFromBits;
0159 using real_type =
0160 absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
0161
0162 while (true) {
0163 const result_type sample =
0164 GenerateRealFromBits<real_type, GeneratePositiveTag, true>(
0165 fast_u64_(gen));
0166 const result_type res = p.a() + (sample * p.range_);
0167 if (res < p.b() || p.range_ <= 0 || !std::isfinite(p.range_)) {
0168 return res;
0169 }
0170
0171 }
0172 }
0173
0174 template <typename CharT, typename Traits, typename RealType>
0175 std::basic_ostream<CharT, Traits>& operator<<(
0176 std::basic_ostream<CharT, Traits>& os,
0177 const uniform_real_distribution<RealType>& x) {
0178 auto saver = random_internal::make_ostream_state_saver(os);
0179 os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
0180 os << x.a() << os.fill() << x.b();
0181 return os;
0182 }
0183
0184 template <typename CharT, typename Traits, typename RealType>
0185 std::basic_istream<CharT, Traits>& operator>>(
0186 std::basic_istream<CharT, Traits>& is,
0187 uniform_real_distribution<RealType>& x) {
0188 using param_type = typename uniform_real_distribution<RealType>::param_type;
0189 using result_type = typename uniform_real_distribution<RealType>::result_type;
0190 auto saver = random_internal::make_istream_state_saver(is);
0191 auto a = random_internal::read_floating_point<result_type>(is);
0192 if (is.fail()) return is;
0193 auto b = random_internal::read_floating_point<result_type>(is);
0194 if (!is.fail()) {
0195 x.param(param_type(a, b));
0196 }
0197 return is;
0198 }
0199 ABSL_NAMESPACE_END
0200 }
0201
0202 #endif