/usr/include/boost/random/detail
Edit: /usr/include/boost/random/detail/int_float_pair.hpp (4178B)
/* boost random/detail/int_float_pair.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
#define BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost {
namespace random {
namespace detail {
template
inline typename boost::make_unsigned::type
generate_one_digit(Engine& eng, std::size_t bits)
{
typedef typename Engine::result_type base_result;
typedef typename boost::make_unsigned::type base_unsigned;
base_unsigned range =
detail::subtract()((eng.max)(), (eng.min)());
base_unsigned y0_mask = (base_unsigned(2) << (bits - 1)) - 1;
base_unsigned y0 = (range + 1) & ~y0_mask;
base_unsigned u;
do {
u = detail::subtract()(eng(), (eng.min)());
} while(y0 != 0 && u > base_unsigned(y0 - 1));
return u & y0_mask;
}
template
std::pair generate_int_float_pair(Engine& eng, boost::mpl::true_)
{
typedef typename Engine::result_type base_result;
typedef typename boost::make_unsigned::type base_unsigned;
base_unsigned range =
detail::subtract()((eng.max)(), (eng.min)());
std::size_t m =
(range == (std::numeric_limits::max)()) ?
std::numeric_limits::digits :
detail::integer_log2(range + 1);
int bucket = 0;
// process as many full digits as possible into the int part
for(std::size_t i = 0; i < w/m; ++i) {
base_unsigned u = generate_one_digit(eng, m);
bucket = (bucket << m) | u;
}
RealType r;
const std::size_t digits = std::numeric_limits::digits;
{
base_unsigned u = generate_one_digit(eng, m);
base_unsigned mask = (base_unsigned(1) << (w%m)) - 1;
bucket = (bucket << (w%m)) | (mask & u);
const RealType mult = RealType(1)/RealType(base_unsigned(1) << (m - w%m));
// zero out unused bits
if (m - w%m > digits) {
u &= ~(base_unsigned(1) << (m - digits));
}
r = RealType(u >> (w%m)) * mult;
}
for(std::size_t i = m - w%m; i + m < digits; ++i) {
base_unsigned u = generate_one_digit(eng, m);
r += u;
r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
}
if (m - w%m < digits)
{
const std::size_t remaining = (digits - m + w%m) % m;
base_unsigned u = generate_one_digit(eng, m);
r += u & ((base_unsigned(2) << (remaining - 1)) - 1);
const RealType mult = RealType(0.5)/RealType(base_unsigned(1) << (remaining - 1));
r *= mult;
}
return std::make_pair(r, bucket);
}
template
inline std::pair generate_int_float_pair(Engine& eng, boost::mpl::false_)
{
int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
RealType r = uniform_01()(eng);
return std::make_pair(r, bucket);
}
template
inline std::pair generate_int_float_pair(Engine& eng)
{
typedef typename Engine::result_type base_result;
return generate_int_float_pair(eng,
boost::is_integral());
}
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP