2
0
mirror of https://github.com/boostorg/random.git synced 2026-02-26 17:02:15 +00:00

Merge [72825] and [72826] from the trunk. Authorized by Beman.

[SVN r72951]
This commit is contained in:
Steven Watanabe
2011-07-07 04:57:37 +00:00
parent a734166dc2
commit fd4efbb298
8 changed files with 103 additions and 45 deletions

View File

@@ -0,0 +1,36 @@
/* boost random/detail/generator_bits.hpp header file
*
* Copyright Steven Watanabe 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_GENERATOR_BITS_HPP
#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
#include <boost/limits.hpp>
namespace boost {
namespace random {
namespace detail {
// This is a temporary measure that retains backwards
// compatibility.
template<class URNG>
struct generator_bits {
static std::size_t value() {
return std::numeric_limits<typename URNG::result_type>::digits;
}
};
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP

View File

@@ -27,6 +27,7 @@
#include <boost/random/detail/const_mod.hpp>
#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/detail/generator_bits.hpp>
#include <boost/random/detail/disable_warnings.hpp>
@@ -87,7 +88,7 @@ void generate_from_real(Engine& eng, Iter begin, Iter end)
{
using std::fmod;
typedef typename Engine::result_type RealType;
const int Bits = Engine::precision();
const int Bits = detail::generator_bits<Engine>::value();
int remaining_bits = 0;
boost::uint_least32_t saved_bits = 0;
RealType multiplier = pow2<RealType>( Bits);

View File

@@ -19,6 +19,7 @@
#include <boost/config.hpp>
#include <boost/integer.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/generator_bits.hpp>
#include <boost/random/detail/disable_warnings.hpp>
@@ -48,7 +49,9 @@ public:
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
std::size_t digits = std::numeric_limits<result_type>::digits;
if(URNG::precision() < digits) digits = URNG::precision();
if(detail::generator_bits<URNG>::value() < digits) {
digits = detail::generator_bits<URNG>::value();
}
return (result_type(2) << (digits - 1)) - 1;
}
base_type& base() { return _rng; }

View File

@@ -108,7 +108,12 @@ public:
{
if(_n >= returned_block) {
// discard values of random number generator
_rng.discard(total_block - _n);
// Don't use discard, since we still need to
// be somewhat compatible with TR1.
// _rng.discard(total_block - _n);
for(std::size_t i = 0; i < total_block - _n; ++i) {
_rng();
}
_n = 0;
}
++_n;
@@ -139,16 +144,6 @@ public:
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (base_type::max)(); }
/**
* INTERNAL ONLY
* Returns the number of random bits.
* This is not part of the standard, and I'm not sure that
* it's the best solution, but something like this is needed
* to implement generate_canonical. For now, mark it as
* an implementation detail.
*/
static std::size_t precision() { return base_type::precision(); }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a \discard_block_engine to a @c std::ostream. */
template<class CharT, class Traits>
@@ -221,6 +216,23 @@ public:
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class URNG, std::size_t p, std::size_t r>
struct generator_bits<discard_block_engine<URNG, p, r> > {
static std::size_t value() { return generator_bits<URNG>::value(); }
};
template<class URNG, int p, int r>
struct generator_bits<discard_block<URNG, p, r> > {
static std::size_t value() { return generator_bits<URNG>::value(); }
};
}
} // namespace random
} // namespace boost

View File

@@ -21,6 +21,7 @@
#include <boost/type_traits/is_integral.hpp>
#include <boost/math/special_functions.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/detail/generator_bits.hpp>
namespace boost {
namespace random {
@@ -56,7 +57,7 @@ RealType generate_canonical_impl(URNG& g, boost::mpl::false_ /*is_integral*/)
BOOST_ASSERT((g.max)() == 1);
typedef typename URNG::result_type base_result;
std::size_t digits = std::numeric_limits<RealType>::digits;
std::size_t engine_bits = g.precision();
std::size_t engine_bits = detail::generator_bits<URNG>::value();
std::size_t b = (std::min)(bits, digits);
RealType R = pow(RealType(2), RealType(engine_bits));
RealType mult = R;

View File

@@ -324,16 +324,6 @@ public:
/** Returns the upper bound of the generators outputs. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); }
/**
* INTERNAL ONLY
* Returns the number of random bits.
* This is not part of the standard, and I'm not sure that
* it's the best solution, but something like this is needed
* to implement generate_canonical. For now, mark it as
* an implementation detail.
*/
static std::size_t precision() { return w; }
/** Returns the next value of the generator. */
result_type operator()()
{
@@ -466,6 +456,25 @@ public:
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class RealType, int w, unsigned int p, unsigned int q>
struct generator_bits<lagged_fibonacci_01_engine<RealType, w, p, q> >
{
static std::size_t value() { return w; }
};
template<class RealType, int w, unsigned int p, unsigned int q>
struct generator_bits<lagged_fibonacci_01<RealType, w, p, q> >
{
static std::size_t value() { return w; }
};
}
#ifdef BOOST_RANDOM_DOXYGEN
namespace detail {
/**

View File

@@ -427,16 +427,6 @@ public:
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return result_type(1); }
/**
* INTERNAL ONLY
* Returns the number of random bits.
* This is not part of the standard, and I'm not sure that
* it's the best solution, but something like this is needed
* to implement generate_canonical. For now, mark it as
* an implementation detail.
*/
static std::size_t precision() { return w; }
/** Returns the next value of the generator. */
result_type operator()()
{
@@ -600,6 +590,23 @@ public:
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
struct generator_bits<subtract_with_carry_01_engine<RealType, w, s, r> > {
static std::size_t value() { return w; }
};
template<class RealType, int w, unsigned s, unsigned r, int v>
struct generator_bits<subtract_with_carry_01<RealType, w, s, r, v> > {
static std::size_t value() { return w; }
};
}
} // namespace random
} // namespace boost