12 #if !defined(RANDOMLIB_RANDOMNUMBER_HPP)
13 #define RANDOMLIB_RANDOMNUMBER_HPP 1
65 STATIC_ASSERT(bits > 0 && bits <= w && (bits < 4 || bits % 4 == 0),
66 "RandomNumber: unsupported value for bits");
74 int Sign()
const throw() {
return _s; }
82 int Floor()
const throw() {
return _s > 0 ? int(_n) : -1 - int(_n); }
86 int Ceiling()
const throw() {
return _s > 0 ? 1 + int(_n) : - int(_n); }
90 unsigned UInteger()
const throw() {
return _n; }
98 int ns = k < 0 ? -1 : 1;
100 for (
size_t k = 0; k <
Size(); ++k)
101 _f[k] = ~_f[k] &
mask;
102 _n = ns > 0 ? k : -(k + 1);
113 if (
this == &t)
return false;
114 if (_s != t._s)
return _s < t._s;
115 if (_n != t._n)
return (_s < 0) ^ (_n < t._n);
116 for (
unsigned k = 0; ; ++k) {
118 const unsigned x =
Digit(r,k);
119 const unsigned y = t.
Digit(r,k);
120 if (x != y)
return (_s < 0) ^ (x < y);
136 bool cmpu =
this != &u, cmpv =
this != &v && &u != &v;
137 if (!(cmpu || cmpv))
return true;
140 if (u._s > _s)
return false;
141 if (u._s < _s) cmpu =
false;
144 if (v._s > _s)
return false;
145 if (v._s < _s) cmpv =
false;
147 if (!(cmpu || cmpv))
return true;
150 if ((_s < 0) ^ (u._n > _n))
return false;
151 if ((_s < 0) ^ (u._n < _n)) cmpu =
false;
154 if ((_s < 0) ^ (v._n > _n))
return false;
155 if ((_s < 0) ^ (v._n < _n)) cmpv =
false;
157 if (!(cmpu || cmpv))
return true;
159 for (
unsigned k = 0; ; ++k) {
163 const unsigned x =
Digit(r,k);
165 const unsigned y = u.
Digit(r,k);
166 if ((_s < 0) ^ (y > x))
return false;
167 if ((_s < 0) ^ (y < x)) cmpu =
false;
170 const unsigned y = v.
Digit(r,k);
171 if ((_s < 0) ^ (y > x))
return false;
172 if ((_s < 0) ^ (y < x)) cmpv =
false;
174 if (!(cmpu || cmpv))
return true;
186 template<
class Random,
typename IntType>
188 for (
int k = 0;; ++k) {
189 if (p <= 0)
return false;
190 if (p >= q)
return true;
193 p = (p << bits) -
Digit(r,k) * q;
207 template<
class Random,
typename IntType>
210 for (
int k = 0;; ++k) {
211 if (j. LessThanEqual(r, - p0, c))
return false;
213 p0 = (p0 << bits) - IntType(
Digit(r,k)) * q;
243 {
return (
const unsigned&)(_f.at(k)); }
251 {
return (
unsigned&)(_f.at(k)); }
258 std::vector<unsigned> z(0);
266 unsigned Size()
const throw() {
return unsigned(_f.size()); }
281 "RandomNumber::Fraction: invalid real type RealType");
282 const int d = std::numeric_limits<RealType>::digits;
283 const int k = (d + bits - 1)/bits;
284 const int kg = (d + bits)/bits;
286 if (
Digit(r, kg - 1) & (1U << (kg * bits - d - 1)))
288 y += std::pow(RealType(2), -d);
289 const RealType fact = std::pow(RealType(2), -bits);
290 RealType mult = RealType(1);
291 for (
int i = 0; i < k; ++i) {
293 y += mult * RealType(i < k - 1 ?
RawDigit(i) :
294 RawDigit(i) & (~0U << (k * bits - d)));
308 template<
typename RealType,
class Random> RealType
Value(
Random& r) {
314 "RandomNumber::Value: invalid real type RealType");
315 const int digits = std::numeric_limits<RealType>::digits,
316 min_exp = std::numeric_limits<RealType>::min_exponent;
319 if (_n) lead = highest_bit_idx(_n);
322 while (
Digit(r, i) == 0 && i < (-min_exp)/bits ) ++i;
323 lead = highest_bit_idx(
RawDigit(i)) - (i + 1) * bits;
325 lead = lead > min_exp ? lead : min_exp;
327 int trail = lead - digits;
329 y = RealType(_n & (~0U << trail));
330 if (_n & (1U << (trail - 1)))
331 y += std::pow(RealType(2), trail);
334 int k = (-trail)/bits;
335 if (
Digit(r, k) & (1U << ((k + 1) * bits + trail - 1)))
337 y += std::pow(RealType(2), trail);
339 k = (-trail - 1 + bits)/bits - 1;
340 const RealType fact = std::pow(RealType(2), -bits);
341 RealType mult = RealType(1);
342 for (
int i = 0; i <= k; ++i) {
346 RawDigit(i) & (~0U << ((k + 1) * bits + trail)));
360 std::pair<double, double>
Range()
const throw() {
362 const double fact = std::pow(
double(2), -bits);
363 double mult = double(1);
364 for (
unsigned i = 0; i <
Size(); ++i) {
368 return std::pair<double, double>(_s > 0 ? y : -(y + mult),
369 _s > 0 ? (y + mult) : -y);
377 {
return unsigned(r.template Integer<bits>()); }
391 std::vector<unsigned> _f;
395 template<
class Random>
void ExpandTo(
Random& r,
size_t k) {
396 size_t l = _f.size();
400 for (
size_t i = l; i < k; ++i)
407 static int highest_bit_idx(
unsigned x)
throw() {
408 if (x == 0)
return 0;
410 if (x & 0xffff0000U) { x >>= 16; r += 16; }
411 if (x & 0x0000ff00U) { x >>= 8; r += 8; }
412 if (x & 0x000000f0U) { x >>= 4; r += 4; }
413 if (x & 0x0000000cU) { x >>= 2; r += 2; }
414 if (x & 0x00000002U) { r += 1; }
420 static const int w = std::numeric_limits<unsigned>::digits;
426 bits == w ? ~0U : ~(~0U << (bits < w ? bits : 0));
437 std::ostream& operator<<(std::ostream& os, const RandomNumber<bits>& n) {
438 const std::ios::fmtflags oldflags = os.flags();
440 os << (t.
Sign() > 0 ?
"+" :
"-");
442 os << std::hex << std::setfill(
'0');
447 const int w = std::numeric_limits<unsigned>::digits;
449 for (
int s = ((w + bits - 1)/bits) * bits - bits; s >= 0; s -= bits) {
450 unsigned d = mask & (i >> s);
457 os << std::setw((bits+3)/4) << d;
462 unsigned s = t.
Size();
463 for (
unsigned i = 0; i < s; ++i)
464 os << std::setw((bits+3)/4) << t.
RawDigit(i);
465 os <<
"..." << std::setfill(
' ');
472 #endif // RANDOMLIB_RANDOMNUMBER_HPP
bool LessThan(Random &r, IntType p, IntType q)
Generate random integers, reals, and booleans.
Infinite precision random numbers.
unsigned UInteger() const
unsigned & RawDigit(unsigned k)
std::pair< double, double > Range() const
const unsigned & RawDigit(unsigned k) const
void swap(RandomNumber &t)
static unsigned RandomDigit(Random &r)
bool LessThan(Random &r, IntType p0, IntType c, IntType q, UniformInteger< IntType, bits > &j)
#define STATIC_ASSERT(cond, reason)
RealType Value(Random &r)
void swap(RandomLib::RandomCanonical< Generator > &r, RandomLib::RandomCanonical< Generator > &s)
static const unsigned mask
bool LessThan(Random &r, RandomNumber &t)
unsigned Digit(Random &r, unsigned k)
RealType Fraction(Random &r)
bool GreaterPair(Random &r, RandomNumber &u, RandomNumber &v)