📄 random
字号:
static const int _MP_len = 5;
typedef _Max_type _MP_arr[_MP_len];
_CRTIMP2_PURE _Max_type __CLRCALL_PURE_OR_CDECL _MP_Get(_MP_arr);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Add(_MP_arr, _Max_type);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Mul(_MP_arr, _Max_type, _Max_type);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Rem(_MP_arr, _Max_type);
// TEMPLATE CLASS linear_congruential
template<class _Ity,
class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
struct _Mul_mod
{ // template class for linear congruential generator where
// _Ty is large enough to hold intermediate result without overflow
_Mul_mod(_Ty _Val = 0)
: _Prev(_Val)
{ // construct
}
_Ty operator()()
{ // return next value
static _Ty _Zero = 0; // to quiet diagnostics
_Ty _Divisor = (_Ty)_Mx;
_Prev = _Mx ? ((_Ity)_Ax * _Prev + (_Ty)_Cx) % _Divisor
: ((_Ity)_Ax * _Prev + (_Ty)_Cx);
if (_Prev < _Zero)
_Prev += (_Ty)_Mx;
return (_Prev);
}
_Ty _Prev;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
class _Mult_prec
{ // template class for linear congruential generator using
// multiple precision arithmetic to avoid overflows
public:
_Mult_prec(_Ty _Val = 0)
: _Prev(_Val)
{ // construct
}
_Ty operator()()
{ // return next value
_MP_arr _Wx;
_MP_Mul(_Wx, _Prev, _Ax);
_MP_Add(_Wx, _Cx);
_MP_Rem(_Wx, _Mx);
_Prev = _MP_Get(_Wx);
return (_Prev);
}
_Ty _Prev;
};
#ifdef _ULONGLONG
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx,
bool>
struct _Select_ulonglong
{ // unsigned long long too small, use multiple precision
typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
struct _Select_ulonglong<_Ty, _Ax, _Cx, _Mx, true>
{ // unsigned long long can hold intermediate result
typedef _Mul_mod<_ULONGLONG, _Ty, _Ax, _Cx, _Mx> _Type;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx,
bool>
struct _Select_ulong
{ // unsigned long too small, try unsigned long long
typedef typename _Select_ulonglong<_Ty, _Ax, _Cx, _Mx,
_Cx < _ULLONG_MAX && _Mx <= (_ULLONG_MAX - _Cx) / _Ax>::_Type _Type;
};
#else /* _ULONGLONG */
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx,
bool>
struct _Select_ulong
{ // unsigned long too small, use multiple precision
typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type;
};
#endif /* _ULONGLONG */
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
struct _Select_ulong<_Ty, _Ax, _Cx, _Mx, true>
{ // unsigned long can hold intermediate result
typedef _Mul_mod<unsigned long, _Ty, _Ax, _Cx, _Mx> _Type;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx,
bool>
struct _Select_uint
{ // unsigned int too small, try unsigned long
typedef typename _Select_ulong<_Ty, _Ax, _Cx, _Mx,
_Cx < ULONG_MAX && _Mx <= (ULONG_MAX - _Cx) / _Ax>::_Type _Type;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
struct _Select_uint<_Ty, _Ax, _Cx, _Mx, true>
{ // unsigned int can hold intermediate result
typedef _Mul_mod<unsigned int, _Ty, _Ax, _Cx, _Mx> _Type;
};
template<class _Ty,
_Max_type _Ax,
_Max_type _Cx,
_Max_type _Mx>
struct _Select
{ // select a type large enough to hold intermediate result
typedef typename _Select_uint<_Ty, _Ax, _Cx, _Mx,
_Cx < UINT_MAX && _Mx <= (UINT_MAX - _Cx) / _Ax>::_Type _Type;
};
template<class _Ty>
struct _Is_numeric
: _Or<_Is_integral<_Ty>::value, _Is_floating_point<_Ty>::value>
{ // determine whether _Ty is a numeric type
};
template<class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
class linear_congruential
{ // template class to implement linear congruential generator
public:
typedef linear_congruential<_Uint, _Ax, _Cx, _Mx> _Myt;
typedef _Uint result_type;
static const _Uint multiplier = _Ax;
static const _Uint increment = _Cx;
static const _Uint modulus = _Mx;
static const _Uint default_seed = 1U;
explicit linear_congruential(_Uint _X0 = default_seed)
{ // construct from initial value
seed(_X0);
}
linear_congruential(const _Myt& _Right)
{ // construct by copying
*this = _Right;
}
linear_congruential(_Myt& _Right)
{ // construct by copying
*this = _Right;
}
#if _HAS_CPP0X
explicit linear_congruential(seed_seq& _Seq)
{ // construct from seed sequence
seed(_Seq);
}
#endif /* _HAS_CPP0X */
template<class _Gen>
linear_congruential(_Gen& _Gx)
{ // construct from generator
seed(_Gx);
}
void seed(_Uint _X0 = default_seed)
{ // reset sequence from numeric value
_Reset(_X0);
}
#if _HAS_CPP0X
static const int _Nw = (_BITS_BYTE * sizeof (_Uint) + 31) / 32;
void seed(seed_seq& _Seq)
{ // reset sequence from seed sequence
_Uint _Arr[3 + _Nw];
int _Lsh = _BITS_BYTE * sizeof (_Uint); // to quiet diagnostics
_Seq.generate(&_Arr[0], &_Arr[3 + _Nw]);
for (int _Idx = _Nw; 0 < --_Idx; )
_Arr[3 + _Idx - 1] |=
_Arr[3 + _Idx] << _Lsh;
_Reset(_Arr[3]);
}
#endif /* _HAS_CPP0X */
template<class _Gen>
void seed(_Gen& _Gx, bool = false)
{ // reset sequence from generator
_Seed(_Gx, _Is_numeric<_Gen>());
}
_Uint (min)() const
{ // return minimum possible generated value
return (_Cx != 0 ? 0 : 1);
}
_Uint (max)() const
{ // return maximum possible generated value
return (_Mx != 0 ? _Mx - 1 : (_STD numeric_limits<_Uint>::max)());
}
_Uint operator()()
{ // return next value
return (_Imp());
}
void discard(unsigned long long _Nskip)
{ // discard _Nskip elements
for (; 0 < _Nskip; --_Nskip)
(*this)();
}
bool _Equals(const _Myt& _Right) const
{ // return true if *this will generate same sequence as _Right
return (_Imp._Prev == _Right._Imp._Prev);
}
template<class _Elem, class _Traits>
_STD basic_ostream<_Elem, _Traits>&
_Write(_STD basic_ostream<_Elem, _Traits>& _Ostr) const
{ // write state to _Ostr
return (_Ostr << _Imp._Prev);
}
private:
template<class _Gen>
void _Seed(_Gen& _Gx, const true_type&)
{ // reset sequence from numeric value
_Reset((_Uint)_Gx);
}
template<class _Gen>
void _Seed(_Gen& _Gx, const false_type&)
{ // reset sequence from generator
_Reset(_Gx());
}
void _Reset(_Uint _X0)
{ // reset sequence
_Uint _Divisor = _Mx; // to quiet diagnostics
_Imp._Prev = _Mx != 0 ? _X0 % _Divisor : _X0;
_RNG_ASSERT(0 < _Imp._Prev || 0 < _Cx,
"invalid argument for linear_congruential::seed");
if (_Imp._Prev == 0 && _Cx == 0)
_Imp._Prev = 1;
}
typename _Select<_Uint, _Ax, _Cx, _Mx>::_Type _Imp;
};
template<class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
bool operator==(
const linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Left,
const linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Right)
{ // return true if _Left will generate same sequence as _Right
return (_Left._Equals(_Right));
}
template<class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
bool operator!=(
const linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Left,
const linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Right)
{ // return true if *this will not generate same sequence as _Right
return (!_Left._Equals(_Right));
}
template<class _Elem,
class _Traits,
class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
_STD basic_istream<_Elem, _Traits>& operator>>(
_STD basic_istream<_Elem, _Traits>& _Istr,
linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Eng)
{ // read state from _Istr
_Wrap_istream<_Elem, _Traits, _Uint> _In(_Istr);
_Eng.seed(_In);
return (_Istr);
}
template<class _Elem,
class _Traits,
class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
_STD basic_ostream<_Elem, _Traits>& operator<<(
_STD basic_ostream<_Elem, _Traits>& _Ostr,
const linear_congruential<_Uint, _Ax, _Cx, _Mx>& _Eng)
{ // write state to _Ostr
return (_Eng._Write(_Ostr));
}
#if _HAS_CPP0X
template<class _Uint,
_Uint _Ax,
_Uint _Cx,
_Uint _Mx>
class linear_congruential_engine
: public linear_congruential<_Uint, _Ax, _Cx, _Mx>
{ // template class to implement linear congruential generator
public:
typedef linear_congruential_engine<_Uint, _Ax, _Cx, _Mx> _Myt;
typedef linear_congruential<_Uint, _Ax, _Cx, _Mx> _Mybase;
explicit linear_congruential_engine(_Uint _X0 = _Mybase::default_seed)
: _Mybase(_X0)
{ // construct from initial value
}
linear_congruential_engine(const _Myt& _Right)
{ // construct by copying
*this = _Right;
}
linear_congruential_engine(_Myt& _Right)
{ // construct by copying
*this = _Right;
}
explicit linear_congruential_engine(seed_seq& _Seq)
: _Mybase(_Seq)
{ // construct from seed sequence
}
template<class _Gen>
linear_congruential_engine(_Gen& _Gx)
: _Mybase(_Gx)
{ // construct from generator
}
static _Uint (min)()
{ // return minimum possible generated value
return (_Cx != 0 ? 0 : 1);
}
static _Uint (max)()
{ // return maximum possible generated value
return (_Mx != 0 ? _Mx - 1 : (_STD numeric_limits<_Uint>::max)());
}
};
#endif /* _HAS_CPP0X */
// TEMPLATE CLASS _Circ_buf FOR subtract_with_carry,
// subtract_with_carry_01, and mersenne_twister
template<class _Ty,
int _Nw>
struct _Circ_buf
{ // template class to hold historical values for generators
_Ty _At(int _Ix) const
{ // return value at current position plus _Ix
return (_Ax[_Base(_Ix)]);
}
bool _Equals(const _Circ_buf& _Right) const
{ // return true if *this holds same values as _Right
const _Ty *_Last1 = _Ax + _Idx, *_Last2 = _Right._Ax + _Right._Idx;
const _Ty *_First, *_Last, *_Other;
bool _Use2 = _Base() < _Right._Base();
if (_Use2)
{ // _Right's range is higher up in the array
// than ours, so scan it first
_First = _Right._Ax + _Right._Base();
_Last = _Last2;
_Other = _Ax + _Base();
}
else
{ // our range is higher up in the array
// than _Right's, so scan ours first
_First = _Ax + _Base();
_Last = _Last1;
_Other = _Right._Ax + _Right._Base();
}
int _N0 = _Nw;
while (_N0)
{ // scan
// note: may need up to three passes; each scan starts at the
// current highest array position and ends at the end of the
// array or the _Idx value, whichever comes first; the
// equality test succeeds only by reaching the _Idx value.
const _Ty *_Limit = _First < _Last ? _Last
: _Use2 ? _Right._Ax + 2 * _Nw
: _Ax + 2 * _Nw;
_N0 -= _Limit - _First;
while (_First != _Limit)
if (*_First++ != *_Other++)
return (false);
_First = _Other;
_Last = _Use2 ? _Last1 : _Last2;
_Other = _Use2 ? _Right._Ax : _Ax;
_Use2 = !_Use2;
}
return (true);
}
unsigned int _Base(int _Ix = 0) const
{ // return _Ix'th historical element (loosely, (_Idx - _Nw) + _Ix)
return ((_Ix += _Idx) < _Nw ? (_Ix + _Nw) : (_Ix - _Nw));
}
unsigned int _Idx;
_Ty _Ax[2 * _Nw];
};
// TEMPLATE CLASS _Swc_base (subtract_with_carry, subtract_with_carry_01)
template<class _Ty,
int _Sx,
int _Rx,
class _Swc_Traits>
class _Swc_base
: public _Circ_buf<_Ty, _Rx>
{ // base template class for subtract_with_carry/_01
public:
typedef _Ty result_type;
typedef _Circ_buf<_Ty, _Rx> _Mybase;
typedef typename _Swc_Traits::_Seed_t _Seed_t;
static const int short_lag = _Sx;
static const int long_lag = _Rx;
_Swc_base()
{ // construct with default seed
seed();
}
_Swc_base(typename _Swc_Traits::_Seed_t _X0)
{ // construct with specified seed
seed(_X0);
}
#if _HAS_CPP0X
_Swc_base(seed_seq& _Seq)
{ // construct from seed sequence
this->seed(_Seq);
}
#endif /* _HAS_CPP0X */
template<class _Gen>
_Swc_base(_Gen& _Gx)
{ // construct with seed values from generator
seed(_Gx);
}
void seed(unsigned long _Value = 19780503U)
{ // set initial values from specified seed value
_Seed(_Value, false, true_type());
}
#if _HAS_CPP0X
static const int _Kx = (_BITS_BYTE * sizeof (_Ty) + 31) / 32;
void seed(seed_seq& _Seq)
{ // reset sequence from seed sequence
unsigned long _Arr[_Kx * _Rx];
_Seq.generate(&_Arr[0], &_Arr[_Kx * _Rx]);
int _Idx0 = 0;
for (int _Ix = 0; _Ix < _Rx; ++_Ix, _Idx0 += _Kx)
{ // pack _Kx words
this->_Ax[_Ix] = _Arr[_Idx0];
for (int _Jx = 0; ++_Jx < _Kx; )
this->_Ax[_Ix] |= (_Ty)_Arr[_Idx0 + _Jx] << (32 * _Jx);
if (_Swc_Traits::_Mod != 0)
this->_Ax[_Ix] %= _Swc_Traits::_Mod;
}
this->_Carry = _Swc_Traits::_Reduce(this->_Ax);
this->_Idx = _Rx;
}
#endif /* _HAS_CPP0X */
template<class _Gen>
void seed(_Gen& _Gx, bool _Readcy = false)
{ // set initial values from range
_Seed(_Gx, _Readcy, _Is_numeric<_Gen>());
}
result_type (min)() const
{ // return minimum possible generated value
return (0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -