1 ///////////////////////////////////////////////////////////////
2 //  Copyright Jens Maurer 2006-1011
3 //  Copyright Steven Watanabe 2011
4 //  Copyright 2012 John Maddock. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
7 
8 #ifndef BOOST_MP_RANDOM_HPP
9 #define BOOST_MP_RANDOM_HPP
10 
11 #ifdef BOOST_MSVC
12 #pragma warning(push)
13 #pragma warning(disable:4127)
14 #endif
15 
16 #include <boost/multiprecision/number.hpp>
17 
18 namespace boost{ namespace random{ namespace detail{
19 //
20 // This is a horrible hack: this declaration has to appear before the definition of
21 // uniform_int_distribution, otherwise it won't be used...
22 // Need to find a better solution, like make Boost.Random safe to use with
23 // UDT's and depricate/remove this header altogether.
24 //
25 template<class Engine, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
26 boost::multiprecision::number<Backend, ExpressionTemplates>
27    generate_uniform_int(Engine& eng, const boost::multiprecision::number<Backend, ExpressionTemplates>& min_value, const boost::multiprecision::number<Backend, ExpressionTemplates>& max_value);
28 
29 }}}
30 
31 #include <boost/random.hpp>
32 #include <boost/mpl/eval_if.hpp>
33 
34 namespace boost{
35 namespace random{
36 namespace detail{
37 
38 template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
39 struct subtract<boost::multiprecision::number<Backend, ExpressionTemplates>, true>
40 {
41   typedef boost::multiprecision::number<Backend, ExpressionTemplates> result_type;
operator ()boost::random::detail::subtract42   result_type operator()(result_type const& x, result_type const& y) { return x - y; }
43 };
44 
45 }
46 
47 template<class Engine, std::size_t w, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
48 class independent_bits_engine<Engine, w, boost::multiprecision::number<Backend, ExpressionTemplates> >
49 {
50 public:
51     typedef Engine base_type;
52     typedef boost::multiprecision::number<Backend, ExpressionTemplates> result_type;
53 
BOOST_PREVENT_MACRO_SUBSTITUTION()54     static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
55     { return 0; }
56     // This is the only function we modify compared to the primary template:
BOOST_PREVENT_MACRO_SUBSTITUTION()57     static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
58     {
59        // This expression allows for the possibility that w == std::numeric_limits<result_type>::digits:
60        return (((result_type(1) << (w - 1)) - 1) << 1) + 1;
61     }
62 
independent_bits_engine()63     independent_bits_engine() { }
64 
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(independent_bits_engine,result_type,seed_arg)65     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(independent_bits_engine,
66         result_type, seed_arg)
67     {
68         _base.seed(seed_arg);
69     }
70 
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(independent_bits_engine,SeedSeq,seq)71     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(independent_bits_engine,
72         SeedSeq, seq)
73     { _base.seed(seq); }
74 
independent_bits_engine(const base_type & base_arg)75     independent_bits_engine(const base_type& base_arg) : _base(base_arg) {}
76 
77     template<class It>
independent_bits_engine(It & first,It last)78     independent_bits_engine(It& first, It last) : _base(first, last) { }
79 
seed()80     void seed() { _base.seed(); }
81 
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(independent_bits_engine,result_type,seed_arg)82     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(independent_bits_engine,
83         result_type, seed_arg)
84     { _base.seed(seed_arg); }
85 
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(independent_bits_engine,SeedSeq,seq)86     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(independent_bits_engine,
87         SeedSeq, seq)
88     { _base.seed(seq); }
89 
seed(It & first,It last)90     template<class It> void seed(It& first, It last)
91     { _base.seed(first, last); }
92 
operator ()()93     result_type operator()()
94     {
95         // While it may seem wasteful to recalculate this
96         // every time, both msvc and gcc can propagate
97         // constants, resolving this at compile time.
98         base_unsigned range =
99             detail::subtract<base_result>()((_base.max)(), (_base.min)());
100         std::size_t m =
101             (range == (std::numeric_limits<base_unsigned>::max)()) ?
102                 std::numeric_limits<base_unsigned>::digits :
103                 detail::integer_log2(range + 1);
104         std::size_t n = (w + m - 1) / m;
105         std::size_t w0, n0;
106         base_unsigned y0, y1;
107         base_unsigned y0_mask, y1_mask;
108         calc_params(n, range, w0, n0, y0, y1, y0_mask, y1_mask);
109         if(base_unsigned(range - y0 + 1) > y0 / n) {
110             // increment n and try again.
111             ++n;
112             calc_params(n, range, w0, n0, y0, y1, y0_mask, y1_mask);
113         }
114 
115         BOOST_ASSERT(n0*w0 + (n - n0)*(w0 + 1) == w);
116 
117         result_type S = 0;
118         for(std::size_t k = 0; k < n0; ++k) {
119             base_unsigned u;
120             do {
121                 u = detail::subtract<base_result>()(_base(), (_base.min)());
122             } while(u > base_unsigned(y0 - 1));
123             S = (S << w0) + (u & y0_mask);
124         }
125         for(std::size_t k = 0; k < (n - n0); ++k) {
126             base_unsigned u;
127             do {
128                 u = detail::subtract<base_result>()(_base(), (_base.min)());
129             } while(u > base_unsigned(y1 - 1));
130             S = (S << (w0 + 1)) + (u & y1_mask);
131         }
132         return S;
133     }
134 
135     /** Fills a range with random values */
136     template<class Iter>
generate(Iter first,Iter last)137     void generate(Iter first, Iter last)
138     { detail::generate_from_int(*this, first, last); }
139 
140     /** Advances the state of the generator by @c z. */
discard(boost::uintmax_t z)141     void discard(boost::uintmax_t z)
142     {
143         for(boost::uintmax_t i = 0; i < z; ++i) {
144             (*this)();
145         }
146     }
147 
base() const148     const base_type& base() const { return _base; }
149 
150     /**
151      * Writes the textual representation if the generator to a @c std::ostream.
152      * The textual representation of the engine is the textual representation
153      * of the base engine.
154      */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,independent_bits_engine,r)155     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, independent_bits_engine, r)
156     {
157         os << r._base;
158         return os;
159     }
160 
161     /**
162      * Reads the state of an @c independent_bits_engine from a
163      * @c std::istream.
164      */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,independent_bits_engine,r)165     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, independent_bits_engine, r)
166     {
167         is >> r._base;
168         return is;
169     }
170 
171     /**
172      * Returns: true iff the two @c independent_bits_engines will
173      * produce the same sequence of values.
174      */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(independent_bits_engine,x,y)175     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(independent_bits_engine, x, y)
176     { return x._base == y._base; }
177     /**
178      * Returns: true iff the two @c independent_bits_engines will
179      * produce different sequences of values.
180      */
181     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(independent_bits_engine)
182 
183 private:
184 
185     /// \cond show_private
186     typedef typename base_type::result_type base_result;
187     typedef typename make_unsigned<base_result>::type base_unsigned;
188 
calc_params(std::size_t n,base_unsigned range,std::size_t & w0,std::size_t & n0,base_unsigned & y0,base_unsigned & y1,base_unsigned & y0_mask,base_unsigned & y1_mask)189     void calc_params(
190         std::size_t n, base_unsigned range,
191         std::size_t& w0, std::size_t& n0,
192         base_unsigned& y0, base_unsigned& y1,
193         base_unsigned& y0_mask, base_unsigned& y1_mask)
194     {
195         BOOST_ASSERT(w >= n);
196         w0 = w/n;
197         n0 = n - w % n;
198         y0_mask = (base_unsigned(2) << (w0 - 1)) - 1;
199         y1_mask = (y0_mask << 1) | 1;
200         y0 = (range + 1) & ~y0_mask;
201         y1 = (range + 1) & ~y1_mask;
202         BOOST_ASSERT(y0 != 0 || base_unsigned(range + 1) == 0);
203     }
204     /// \endcond
205 
206     Engine _base;
207 };
208 
209 template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
210 class uniform_smallint<boost::multiprecision::number<Backend, ExpressionTemplates> >
211 {
212 public:
213     typedef boost::multiprecision::number<Backend, ExpressionTemplates> input_type;
214     typedef boost::multiprecision::number<Backend, ExpressionTemplates> result_type;
215 
216     class param_type
217     {
218     public:
219 
220         typedef uniform_smallint distribution_type;
221 
222         /** constructs the parameters of a @c uniform_smallint distribution. */
param_type(result_type const & min_arg=0,result_type const & max_arg=9)223         param_type(result_type const& min_arg = 0, result_type const& max_arg = 9)
224           : _min(min_arg), _max(max_arg)
225         {
226             BOOST_ASSERT(_min <= _max);
227         }
228 
229         /** Returns the minimum value. */
a() const230         result_type a() const { return _min; }
231         /** Returns the maximum value. */
b() const232         result_type b() const { return _max; }
233 
234 
235         /** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,param_type,parm)236         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
237         {
238             os << parm._min << " " << parm._max;
239             return os;
240         }
241 
242         /** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,param_type,parm)243         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
244         {
245             is >> parm._min >> std::ws >> parm._max;
246             return is;
247         }
248 
249         /** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type,lhs,rhs)250         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
251         { return lhs._min == rhs._min && lhs._max == rhs._max; }
252 
253         /** Returns true if the two sets of parameters are different. */
254         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
255 
256     private:
257         result_type _min;
258         result_type _max;
259     };
260 
261     /**
262      * Constructs a @c uniform_smallint. @c min and @c max are the
263      * lower and upper bounds of the output range, respectively.
264      */
uniform_smallint(result_type const & min_arg=0,result_type const & max_arg=9)265     explicit uniform_smallint(result_type const& min_arg = 0, result_type const& max_arg = 9)
266       : _min(min_arg), _max(max_arg) {}
267 
268     /**
269      * Constructs a @c uniform_smallint from its parameters.
270      */
uniform_smallint(const param_type & parm)271     explicit uniform_smallint(const param_type& parm)
272       : _min(parm.a()), _max(parm.b()) {}
273 
274     /** Returns the minimum value of the distribution. */
a() const275     result_type a() const { return _min; }
276     /** Returns the maximum value of the distribution. */
b() const277     result_type b() const { return _max; }
278     /** Returns the minimum value of the distribution. */
BOOST_PREVENT_MACRO_SUBSTITUTION() const279     result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
280     /** Returns the maximum value of the distribution. */
BOOST_PREVENT_MACRO_SUBSTITUTION() const281     result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
282 
283     /** Returns the parameters of the distribution. */
param() const284     param_type param() const { return param_type(_min, _max); }
285     /** Sets the parameters of the distribution. */
param(const param_type & parm)286     void param(const param_type& parm)
287     {
288         _min = parm.a();
289         _max = parm.b();
290     }
291 
292     /**
293      * Effects: Subsequent uses of the distribution do not depend
294      * on values produced by any engine prior to invoking reset.
295      */
reset()296     void reset() { }
297 
298     /** Returns a value uniformly distributed in the range [min(), max()]. */
299     template<class Engine>
operator ()(Engine & eng) const300     result_type operator()(Engine& eng) const
301     {
302         typedef typename Engine::result_type base_result;
303         return generate(eng, boost::is_integral<base_result>());
304     }
305 
306     /** Returns a value uniformly distributed in the range [param.a(), param.b()]. */
307     template<class Engine>
operator ()(Engine & eng,const param_type & parm) const308     result_type operator()(Engine& eng, const param_type& parm) const
309     { return uniform_smallint(parm)(eng); }
310 
311     /** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,uniform_smallint,ud)312     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud)
313     {
314         os << ud._min << " " << ud._max;
315         return os;
316     }
317 
318     /** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,uniform_smallint,ud)319     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud)
320     {
321         is >> ud._min >> std::ws >> ud._max;
322         return is;
323     }
324 
325     /**
326      * Returns true if the two distributions will produce identical
327      * sequences of values given equal generators.
328      */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint,lhs,rhs)329     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs)
330     { return lhs._min == rhs._min && lhs._max == rhs._max; }
331 
332     /**
333      * Returns true if the two distributions may produce different
334      * sequences of values given equal generators.
335      */
336     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint)
337 
338 private:
339 
340     // \cond show_private
341     template<class Engine>
generate(Engine & eng,boost::mpl::true_) const342     result_type generate(Engine& eng, boost::mpl::true_) const
343     {
344         // equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min,
345         // but guarantees no overflow.
346         typedef typename Engine::result_type base_result;
347         typedef typename boost::make_unsigned<base_result>::type base_unsigned;
348         typedef result_type  range_type;
349         range_type range = random::detail::subtract<result_type>()(_max, _min);
350         base_unsigned base_range =
351             random::detail::subtract<result_type>()((eng.max)(), (eng.min)());
352         base_unsigned val =
353             random::detail::subtract<base_result>()(eng(), (eng.min)());
354         if(range >= base_range) {
355             return boost::random::detail::add<range_type, result_type>()(
356                 static_cast<range_type>(val), _min);
357         } else {
358             base_unsigned modulus = static_cast<base_unsigned>(range) + 1;
359             return boost::random::detail::add<range_type, result_type>()(
360                 static_cast<range_type>(val % modulus), _min);
361         }
362     }
363 
364     template<class Engine>
generate(Engine & eng,boost::mpl::false_) const365     result_type generate(Engine& eng, boost::mpl::false_) const
366     {
367         typedef typename Engine::result_type base_result;
368         typedef result_type                  range_type;
369         range_type range = random::detail::subtract<result_type>()(_max, _min);
370         base_result val = boost::uniform_01<base_result>()(eng);
371         // what is the worst that can possibly happen here?
372         // base_result may not be able to represent all the values in [0, range]
373         // exactly.  If this happens, it will cause round off error and we
374         // won't be able to produce all the values in the range.  We don't
375         // care about this because the user has already told us not to by
376         // using uniform_smallint.  However, we do need to be careful
377         // to clamp the result, or floating point rounding can produce
378         // an out of range result.
379         range_type offset = static_cast<range_type>(val * (range + 1));
380         if(offset > range) return _max;
381         return boost::random::detail::add<range_type, result_type>()(offset , _min);
382     }
383     // \endcond
384 
385     result_type _min;
386     result_type _max;
387 };
388 
389 
390 namespace detail{
391 
392 template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
393 struct select_uniform_01<boost::multiprecision::number<Backend, ExpressionTemplates> >
394 {
395   template<class RealType>
396   struct apply
397   {
398     typedef new_uniform_01<boost::multiprecision::number<Backend, ExpressionTemplates> > type;
399   };
400 };
401 
402 template<class Engine, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
403 boost::multiprecision::number<Backend, ExpressionTemplates>
generate_uniform_int(Engine & eng,const boost::multiprecision::number<Backend,ExpressionTemplates> & min_value,const boost::multiprecision::number<Backend,ExpressionTemplates> & max_value,boost::mpl::true_)404    generate_uniform_int(
405     Engine& eng, const boost::multiprecision::number<Backend, ExpressionTemplates>& min_value, const boost::multiprecision::number<Backend, ExpressionTemplates>& max_value,
406     boost::mpl::true_ /** is_integral<Engine::result_type> */)
407 {
408     typedef boost::multiprecision::number<Backend, ExpressionTemplates> result_type;
409     // Since we're using big-numbers, use the result type for all internal calculations:
410     typedef result_type range_type;
411     typedef result_type base_result;
412     typedef result_type base_unsigned;
413     const range_type range = random::detail::subtract<result_type>()(max_value, min_value);
414     const base_result bmin = (eng.min)();
415     const base_unsigned brange =
416       random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
417 
418     if(range == 0) {
419       return min_value;
420     } else if(brange == range) {
421       // this will probably never happen in real life
422       // basically nothing to do; just take care we don't overflow / underflow
423       base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
424       return random::detail::add<base_unsigned, result_type>()(v, min_value);
425     } else if(brange < range) {
426       // use rejection method to handle things like 0..3 --> 0..4
427       for(;;) {
428         // concatenate several invocations of the base RNG
429         // take extra care to avoid overflows
430 
431         //  limit == floor((range+1)/(brange+1))
432         //  Therefore limit*(brange+1) <= range+1
433         range_type limit;
434         if(std::numeric_limits<range_type>::is_bounded && (range == (std::numeric_limits<range_type>::max)())) {
435           limit = range/(range_type(brange)+1);
436           if(range % (range_type(brange)+1) == range_type(brange))
437             ++limit;
438         } else {
439           limit = (range+1)/(range_type(brange)+1);
440         }
441 
442         // We consider "result" as expressed to base (brange+1):
443         // For every power of (brange+1), we determine a random factor
444         range_type result = range_type(0);
445         range_type mult = range_type(1);
446 
447         // loop invariants:
448         //  result < mult
449         //  mult <= range
450         while(mult <= limit) {
451           // Postcondition: result <= range, thus no overflow
452           //
453           // limit*(brange+1)<=range+1                   def. of limit       (1)
454           // eng()-bmin<=brange                          eng() post.         (2)
455           // and mult<=limit.                            loop condition      (3)
456           // Therefore mult*(eng()-bmin+1)<=range+1      by (1),(2),(3)      (4)
457           // Therefore mult*(eng()-bmin)+mult<=range+1   rearranging (4)     (5)
458           // result<mult                                 loop invariant      (6)
459           // Therefore result+mult*(eng()-bmin)<range+1  by (5), (6)         (7)
460           //
461           // Postcondition: result < mult*(brange+1)
462           //
463           // result<mult                                 loop invariant      (1)
464           // eng()-bmin<=brange                          eng() post.         (2)
465           // Therefore result+mult*(eng()-bmin) <
466           //           mult+mult*(eng()-bmin)            by (1)              (3)
467           // Therefore result+(eng()-bmin)*mult <
468           //           mult+mult*brange                  by (2), (3)         (4)
469           // Therefore result+(eng()-bmin)*mult <
470           //           mult*(brange+1)                   by (4)
471           result += static_cast<range_type>(random::detail::subtract<base_result>()(eng(), bmin) * mult);
472 
473           // equivalent to (mult * (brange+1)) == range+1, but avoids overflow.
474           if(mult * range_type(brange) == range - mult + 1) {
475               // The destination range is an integer power of
476               // the generator's range.
477               return(result);
478           }
479 
480           // Postcondition: mult <= range
481           //
482           // limit*(brange+1)<=range+1                   def. of limit       (1)
483           // mult<=limit                                 loop condition      (2)
484           // Therefore mult*(brange+1)<=range+1          by (1), (2)         (3)
485           // mult*(brange+1)!=range+1                    preceding if        (4)
486           // Therefore mult*(brange+1)<range+1           by (3), (4)         (5)
487           //
488           // Postcondition: result < mult
489           //
490           // See the second postcondition on the change to result.
491           mult *= range_type(brange)+range_type(1);
492         }
493         // loop postcondition: range/mult < brange+1
494         //
495         // mult > limit                                  loop condition      (1)
496         // Suppose range/mult >= brange+1                Assumption          (2)
497         // range >= mult*(brange+1)                      by (2)              (3)
498         // range+1 > mult*(brange+1)                     by (3)              (4)
499         // range+1 > (limit+1)*(brange+1)                by (1), (4)         (5)
500         // (range+1)/(brange+1) > limit+1                by (5)              (6)
501         // limit < floor((range+1)/(brange+1))           by (6)              (7)
502         // limit==floor((range+1)/(brange+1))            def. of limit       (8)
503         // not (2)                                       reductio            (9)
504         //
505         // loop postcondition: (range/mult)*mult+(mult-1) >= range
506         //
507         // (range/mult)*mult + range%mult == range       identity            (1)
508         // range%mult < mult                             def. of %           (2)
509         // (range/mult)*mult+mult > range                by (1), (2)         (3)
510         // (range/mult)*mult+(mult-1) >= range           by (3)              (4)
511         //
512         // Note that the maximum value of result at this point is (mult-1),
513         // so after this final step, we generate numbers that can be
514         // at least as large as range.  We have to really careful to avoid
515         // overflow in this final addition and in the rejection.  Anything
516         // that overflows is larger than range and can thus be rejected.
517 
518         // range/mult < brange+1  -> no endless loop
519         range_type result_increment =
520             generate_uniform_int(
521                 eng,
522                 static_cast<range_type>(0),
523                 static_cast<range_type>(range/mult),
524                 boost::mpl::true_());
525         if(std::numeric_limits<range_type>::is_bounded && ((std::numeric_limits<range_type>::max)() / mult < result_increment)) {
526           // The multiplication would overflow.  Reject immediately.
527           continue;
528         }
529         result_increment *= mult;
530         // unsigned integers are guaranteed to wrap on overflow.
531         result += result_increment;
532         if(result < result_increment) {
533           // The addition overflowed.  Reject.
534           continue;
535         }
536         if(result > range) {
537           // Too big.  Reject.
538           continue;
539         }
540         return random::detail::add<range_type, result_type>()(result, min_value);
541       }
542     } else {                   // brange > range
543       range_type bucket_size;
544       // it's safe to add 1 to range, as long as we cast it first,
545       // because we know that it is less than brange.  However,
546       // we do need to be careful not to cause overflow by adding 1
547       // to brange.
548       if(std::numeric_limits<base_unsigned>::is_bounded && (brange == (std::numeric_limits<base_unsigned>::max)())) {
549         bucket_size = brange / (range+1);
550         if(brange % (range+1) == range) {
551           ++bucket_size;
552         }
553       } else {
554         bucket_size = (brange+1) / (range+1);
555       }
556       for(;;) {
557         range_type result =
558           random::detail::subtract<base_result>()(eng(), bmin);
559         result /= bucket_size;
560         // result and range are non-negative, and result is possibly larger
561         // than range, so the cast is safe
562         if(result <= range)
563           return result + min_value;
564       }
565     }
566 }
567 
568 template<class Engine, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
569 inline boost::multiprecision::number<Backend, ExpressionTemplates>
generate_uniform_int(Engine & eng,const boost::multiprecision::number<Backend,ExpressionTemplates> & min_value,const boost::multiprecision::number<Backend,ExpressionTemplates> & max_value)570    generate_uniform_int(Engine& eng, const boost::multiprecision::number<Backend, ExpressionTemplates>& min_value, const boost::multiprecision::number<Backend, ExpressionTemplates>& max_value)
571 {
572     typedef typename Engine::result_type base_result;
573     typedef typename mpl::or_<boost::is_integral<base_result>, mpl::bool_<boost::multiprecision::number_category<Backend>::value == boost::multiprecision::number_kind_integer> >::type tag_type;
574     return generate_uniform_int(eng, min_value, max_value,
575         tag_type());
576 }
577 
578 template<class Engine, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
generate_uniform_real(Engine & eng,const boost::multiprecision::number<Backend,ExpressionTemplates> & min_value,const boost::multiprecision::number<Backend,ExpressionTemplates> & max_value)579 inline boost::multiprecision::number<Backend, ExpressionTemplates> generate_uniform_real(Engine& eng, const boost::multiprecision::number<Backend, ExpressionTemplates>& min_value, const boost::multiprecision::number<Backend, ExpressionTemplates>& max_value)
580 {
581    if(max_value / 2 - min_value / 2 > (std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >::max)() / 2)
582       return 2 * generate_uniform_real(eng, boost::multiprecision::number<Backend, ExpressionTemplates>(min_value / 2), boost::multiprecision::number<Backend, ExpressionTemplates>(max_value / 2));
583    typedef typename Engine::result_type base_result;
584    return generate_uniform_real(eng, min_value, max_value,
585       boost::is_integral<base_result>());
586 }
587 
588 } // detail
589 
590 
591 }} // namespaces
592 
593 #ifdef BOOST_MSVC
594 #pragma warning(pop)
595 #endif
596 
597 #endif
598