Index: boost/random/linear_feedback_shift.hpp =================================================================== --- boost/random/linear_feedback_shift.hpp (revision 57008) +++ boost/random/linear_feedback_shift.hpp (working copy) @@ -77,7 +77,12 @@ seed(first, last); } - void seed(UIntType s0 = 341) { assert(s0 >= (1 << (w-k))); value = s0; } + void seed(UIntType s0 = 341) { + if(s0 < (1 << (w-k))) { + s0 += 1 << (w-k); + } + value = s0; + } template void seed(It& first, It last) { if(first == last) Index: boost/random/linear_congruential.hpp =================================================================== --- boost/random/linear_congruential.hpp (revision 57008) +++ boost/random/linear_congruential.hpp (working copy) @@ -54,12 +54,9 @@ // BOOST_STATIC_ASSERT(m == 0 || c < m); explicit linear_congruential(IntType x0 = 1) - : _modulus(modulus), _x(_modulus ? (x0 % _modulus) : x0) + : _modulus(modulus) { - assert(c || x0); /* if c == 0 and x(0) == 0 then x(n) = 0 for all n */ - // overflow check - // disabled because it gives spurious "divide by zero" gcc warnings - // assert(m == 0 || (a*(m-1)+c) % m == (c < a ? c-a+m : c-a)); + seed(x0); // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS @@ -77,8 +74,18 @@ // compiler-generated copy constructor and assignment operator are fine void seed(IntType x0 = 1) { - assert(c || x0); - _x = (_modulus ? (x0 % _modulus) : x0); + // wrap _x if it doesn't fit in the destination type + if(_modulus == 0) { + _x = x0; + } else { + _x = x0 % (modulus - min()); + } + // adjust to the correct range + if(_x < min()) { + _x += (modulus - min()); + } + assert(_x >= min()); + assert(_x <= max()); } template @@ -86,8 +93,7 @@ { if(first == last) throw std::invalid_argument("linear_congruential::seed"); - IntType value = *first++; - _x = (_modulus ? (value % _modulus) : value); + seed(*first++); } result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return c == 0 ? 1 : 0; } @@ -261,7 +267,7 @@ if(sizeof(T) < sizeof(uint64_t)) { return (static_cast(x) << 16) | 0x330e; } else { - return(static_cast(x)); + return(static_cast(x)); } } static uint64_t cnv(float x) { return(static_cast(x)); } Index: libs/random/instantiate.cpp =================================================================== --- libs/random/instantiate.cpp (revision 57008) +++ libs/random/instantiate.cpp (working copy) @@ -133,53 +133,63 @@ boost::gamma_distribution(1)); } -template -void test_seed(URNG & urng, const T & t) { - URNG urng2(t); - BOOST_CHECK(urng == urng2); - urng2.seed(t); - BOOST_CHECK(urng == urng2); +template +void test_seed_conversion(URNG & urng, const T & t, const Converted &) { + Converted c = static_cast(t); + if(static_cast(c) == t) { + URNG urng2(c); + BOOST_CHECK_MESSAGE(urng == urng2, std::string("Testing seed constructor: ") + typeid(Converted).name()); + urng2.seed(c); + BOOST_CHECK(urng == urng2); + } } // rand48 uses non-standard seeding -template -void test_seed(boost::rand48 & urng, const T & t) { +template +void test_seed_conversion(boost::rand48 & urng, const T & t, const Converted &) { boost::rand48 urng2(t); urng2.seed(t); } template -void instantiate_seed(const URNG &, const ResultType &) { +void test_seed(const URNG &, const ResultType & v) { + typename URNG::result_type value = static_cast(v); + + URNG urng(value); + + // integral types + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); +#if !defined(BOOST_NO_INT64_T) + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); +#endif + + // floating point types + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); + test_seed_conversion(urng, value, static_cast(0)); +} + +template +void instantiate_seed(const URNG & urng, const ResultType &) { { URNG urng; URNG urng2; urng2.seed(); BOOST_CHECK(urng == urng2); } - { - int value = 127; - URNG urng(value); - - // integral types - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); -#if !defined(BOOST_NO_INT64_T) - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); -#endif - - // floating point types - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - test_seed(urng, static_cast(value)); - } + test_seed(urng, 0); + test_seed(urng, 127); + test_seed(urng, 539157235); + test_seed(urng, ~0u); } template