1 /* boost random/uniform_01.hpp header file
3 * Copyright Jens Maurer 2000-2001
4 * Distributed under the Boost Software License, Version 1.0. (See
5 * accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
8 * See http://www.boost.org for most recent version including documentation.
10 * $Id: uniform_01.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
13 * 2001-02-18 moved to individual header files
16 #ifndef BOOST_RANDOM_UNIFORM_01_HPP
17 #define BOOST_RANDOM_UNIFORM_01_HPP
20 #include <boost/config.hpp>
21 #include <boost/limits.hpp>
22 #include <boost/static_assert.hpp>
23 #include <boost/random/detail/config.hpp>
24 #include <boost/random/detail/pass_through_engine.hpp>
26 #include <boost/random/detail/disable_warnings.hpp>
30 #ifdef BOOST_RANDOM_DOXYGEN
33 * The distribution function uniform_01 models a \random_distribution.
34 * On each invocation, it returns a random floating-point value
35 * uniformly distributed in the range [0..1).
37 * The template parameter RealType shall denote a float-like value type
38 * with support for binary operators +, -, and /.
40 * Note: The current implementation is buggy, because it may not fill
41 * all of the mantissa with random bits. I'm unsure how to fill a
42 * (to-be-invented) @c boost::bigfloat class with random bits efficiently.
43 * It's probably time for a traits class.
45 template<class RealType = double>
49 typedef RealType input_type;
50 typedef RealType result_type;
51 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const;
52 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const;
55 template<class Engine>
56 result_type operator()(Engine& eng);
58 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
59 template<class CharT, class Traits>
60 friend std::basic_ostream<CharT,Traits>&
61 operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
66 template<class CharT, class Traits>
67 friend std::basic_istream<CharT,Traits>&
68 operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
79 template<class RealType>
83 typedef RealType input_type;
84 typedef RealType result_type;
85 // compiler-generated copy ctor and copy assignment are fine
86 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
87 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
90 template<class Engine>
91 result_type operator()(Engine& eng) {
93 typedef typename Engine::result_type base_result;
94 result_type factor = result_type(1) /
95 (result_type((eng.max)()-(eng.min)()) +
96 result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));
97 result_type result = result_type(eng() - (eng.min)()) * factor;
98 if (result < result_type(1))
103 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
104 template<class CharT, class Traits>
105 friend std::basic_ostream<CharT,Traits>&
106 operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
111 template<class CharT, class Traits>
112 friend std::basic_istream<CharT,Traits>&
113 operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
120 template<class UniformRandomNumberGenerator, class RealType>
121 class backward_compatible_uniform_01
123 typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
124 typedef boost::random::detail::pass_through_engine<UniformRandomNumberGenerator> internal_engine_type;
126 typedef UniformRandomNumberGenerator base_type;
127 typedef RealType result_type;
129 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
131 #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
132 BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
135 explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
137 _factor(result_type(1) /
138 (result_type((_rng.max)()-(_rng.min)()) +
139 result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
142 // compiler-generated copy ctor and copy assignment are fine
144 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
145 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
146 typename traits::value_type& base() { return _rng.base(); }
147 const typename traits::value_type& base() const { return _rng.base(); }
150 result_type operator()() {
152 result_type result = result_type(_rng() - (_rng.min)()) * _factor;
153 if (result < result_type(1))
158 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
159 template<class CharT, class Traits>
160 friend std::basic_ostream<CharT,Traits>&
161 operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)
167 template<class CharT, class Traits>
168 friend std::basic_istream<CharT,Traits>&
169 operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)
177 typedef typename internal_engine_type::result_type base_result;
178 internal_engine_type _rng;
182 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
183 // A definition is required even for integral static constants
184 template<class UniformRandomNumberGenerator, class RealType>
185 const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
188 template<class UniformRandomNumberGenerator>
189 struct select_uniform_01
191 template<class RealType>
194 typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;
199 struct select_uniform_01<float>
201 template<class RealType>
204 typedef new_uniform_01<float> type;
209 struct select_uniform_01<double>
211 template<class RealType>
214 typedef new_uniform_01<double> type;
219 struct select_uniform_01<long double>
221 template<class RealType>
224 typedef new_uniform_01<long double> type;
230 // Because it is so commonly used: uniform distribution on the real [0..1)
231 // range. This allows for specializations to avoid a costly int -> float
232 // conversion plus float multiplication
233 template<class UniformRandomNumberGenerator = double, class RealType = double>
235 : public detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type
237 typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;
238 typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
243 explicit uniform_01(typename traits::rvalue_type rng)
248 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
249 template<class CharT, class Traits>
250 friend std::basic_ostream<CharT,Traits>&
251 operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
253 os << static_cast<const impl_type&>(u);
257 template<class CharT, class Traits>
258 friend std::basic_istream<CharT,Traits>&
259 operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
261 is >> static_cast<impl_type&>(u);
271 #include <boost/random/detail/enable_warnings.hpp>
273 #endif // BOOST_RANDOM_UNIFORM_01_HPP