]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/random/detail/int_float_pair.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / random / detail / int_float_pair.hpp
CommitLineData
b32b8144
FG
1/* boost random/detail/int_float_pair.hpp header file
2 *
3 * Copyright Jens Maurer 2000-2001
4 * Copyright Steven Watanabe 2010-2011
5 * Distributed under the Boost Software License, Version 1.0. (See
6 * accompanying file LICENSE_1_0.txt or copy at
7 * http://www.boost.org/LICENSE_1_0.txt)
8 *
9 * See http://www.boost.org for most recent version including documentation.
10 *
11 * $Id$
12 *
13 */
14
15#ifndef BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
16#define BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
17
18#include <utility>
19#include <boost/integer.hpp>
20#include <boost/integer/integer_mask.hpp>
21#include <boost/type_traits/make_unsigned.hpp>
22#include <boost/type_traits/is_integral.hpp>
23#include <boost/random/uniform_01.hpp>
24#include <boost/random/uniform_int_distribution.hpp>
25#include <boost/random/detail/signed_unsigned_tools.hpp>
26#include <boost/random/detail/integer_log2.hpp>
b32b8144
FG
27
28namespace boost {
29namespace random {
30namespace detail {
31
32template<class Engine>
33inline typename boost::make_unsigned<typename Engine::result_type>::type
34generate_one_digit(Engine& eng, std::size_t bits)
35{
36 typedef typename Engine::result_type base_result;
37 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
38
39 base_unsigned range =
40 detail::subtract<base_result>()((eng.max)(), (eng.min)());
41 base_unsigned y0_mask = (base_unsigned(2) << (bits - 1)) - 1;
42 base_unsigned y0 = (range + 1) & ~y0_mask;
43 base_unsigned u;
44 do {
45 u = detail::subtract<base_result>()(eng(), (eng.min)());
46 } while(y0 != 0 && u > base_unsigned(y0 - 1));
47 return u & y0_mask;
48}
49
50template<class RealType, std::size_t w, class Engine>
20effc67 51std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::true_type)
b32b8144
FG
52{
53 typedef typename Engine::result_type base_result;
54 typedef typename boost::make_unsigned<base_result>::type base_unsigned;
55
56 base_unsigned range =
57 detail::subtract<base_result>()((eng.max)(), (eng.min)());
58
59 std::size_t m =
60 (range == (std::numeric_limits<base_unsigned>::max)()) ?
61 std::numeric_limits<base_unsigned>::digits :
62 detail::integer_log2(range + 1);
63
64 int bucket = 0;
65 // process as many full digits as possible into the int part
66 for(std::size_t i = 0; i < w/m; ++i) {
67 base_unsigned u = generate_one_digit(eng, m);
68 bucket = (bucket << m) | u;
69 }
70 RealType r;
71
72 const std::size_t digits = std::numeric_limits<RealType>::digits;
73 {
74 base_unsigned u = generate_one_digit(eng, m);
75 base_unsigned mask = (base_unsigned(1) << (w%m)) - 1;
76 bucket = (bucket << (w%m)) | (mask & u);
77 const RealType mult = RealType(1)/RealType(base_unsigned(1) << (m - w%m));
78 // zero out unused bits
79 if (m - w%m > digits) {
80 u &= ~(base_unsigned(1) << (m - digits));
81 }
82 r = RealType(u >> (w%m)) * mult;
83 }
20effc67 84 for(std::size_t i = m - w%m; i + m < digits; i += m) {
b32b8144
FG
85 base_unsigned u = generate_one_digit(eng, m);
86 r += u;
87 r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
88 }
89 if (m - w%m < digits)
90 {
91 const std::size_t remaining = (digits - m + w%m) % m;
92 base_unsigned u = generate_one_digit(eng, m);
93 r += u & ((base_unsigned(2) << (remaining - 1)) - 1);
94 const RealType mult = RealType(0.5)/RealType(base_unsigned(1) << (remaining - 1));
95 r *= mult;
96 }
97 return std::make_pair(r, bucket);
98}
99
100template<class RealType, std::size_t w, class Engine>
20effc67 101inline std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::false_type)
b32b8144
FG
102{
103 int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
104 RealType r = uniform_01<RealType>()(eng);
105 return std::make_pair(r, bucket);
106}
107
108template<class RealType, std::size_t w, class Engine>
109inline std::pair<RealType, int> generate_int_float_pair(Engine& eng)
110{
111 typedef typename Engine::result_type base_result;
112 return generate_int_float_pair<RealType, w>(eng,
113 boost::is_integral<base_result>());
114}
115
116} // namespace detail
117} // namespace random
118} // namespace boost
119
120#endif // BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP