Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/multiprecision/random.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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; | |
42 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 | |
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: | |
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 | |
63 independent_bits_engine() { } | |
64 | |
65 BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(independent_bits_engine, | |
66 result_type, seed_arg) | |
67 { | |
68 _base.seed(seed_arg); | |
69 } | |
70 | |
71 BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(independent_bits_engine, | |
72 SeedSeq, seq) | |
73 { _base.seed(seq); } | |
74 | |
75 independent_bits_engine(const base_type& base_arg) : _base(base_arg) {} | |
76 | |
77 template<class It> | |
78 independent_bits_engine(It& first, It last) : _base(first, last) { } | |
79 | |
80 void seed() { _base.seed(); } | |
81 | |
82 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(independent_bits_engine, | |
83 result_type, seed_arg) | |
84 { _base.seed(seed_arg); } | |
85 | |
86 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(independent_bits_engine, | |
87 SeedSeq, seq) | |
88 { _base.seed(seq); } | |
89 | |
90 template<class It> void seed(It& first, It last) | |
91 { _base.seed(first, last); } | |
92 | |
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> | |
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. */ | |
141 void discard(boost::uintmax_t z) | |
142 { | |
143 for(boost::uintmax_t i = 0; i < z; ++i) { | |
144 (*this)(); | |
145 } | |
146 } | |
147 | |
148 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 */ | |
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 */ | |
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 */ | |
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 | |
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. */ | |
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. */ | |
230 result_type a() const { return _min; } | |
231 /** Returns the maximum value. */ | |
232 result_type b() const { return _max; } | |
233 | |
234 | |
235 /** Writes the parameters to a @c std::ostream. */ | |
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. */ | |
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. */ | |
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 */ | |
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 */ | |
271 explicit uniform_smallint(const param_type& parm) | |
272 : _min(parm.a()), _max(parm.b()) {} | |
273 | |
274 /** Returns the minimum value of the distribution. */ | |
275 result_type a() const { return _min; } | |
276 /** Returns the maximum value of the distribution. */ | |
277 result_type b() const { return _max; } | |
278 /** Returns the minimum value of the distribution. */ | |
279 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; } | |
280 /** Returns the maximum value of the distribution. */ | |
281 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; } | |
282 | |
283 /** Returns the parameters of the distribution. */ | |
284 param_type param() const { return param_type(_min, _max); } | |
285 /** Sets the parameters of the distribution. */ | |
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 */ | |
296 void reset() { } | |
297 | |
298 /** Returns a value uniformly distributed in the range [min(), max()]. */ | |
299 template<class Engine> | |
300 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> | |
308 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. */ | |
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. */ | |
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 */ | |
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> | |
342 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> | |
365 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> | |
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> | |
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 } // detail | |
579 | |
580 | |
581 }} // namespaces | |
582 | |
583 #ifdef BOOST_MSVC | |
584 #pragma warning(pop) | |
585 #endif | |
586 | |
587 #endif |