template<class _Diff,
class _Urng>
class _Rng_from_urng
{ // wrap a URNG as an RNG
public:
explicit _Rng_from_urng(_Urng& _Func)
: _Ref(_Func), _Bits(CHAR_BIT * sizeof(_Udiff)), _Bmask(_Udiff(-1))
{ // construct from URNG
for (; (_Urng::max)() - (_Urng::min)() < _Bmask; _Bmask >>= 1)
--_Bits;
}
_Diff operator()(_Diff _Index)
{ // adapt _Urng closed range to [0, _Index)
for (;;)
{ // try a sample random value
_Udiff _Ret = 0; // random bits
_Udiff _Mask = 0; // 2^N - 1, _Ret is within [0, _Mask]
while (_Mask < _Udiff(_Index - 1))
{ // need more random bits
_Ret <<= _Bits - 1; // avoid full shift
_Ret <<= 1;
_Ret |= _Get_bits();
_Mask <<= _Bits - 1; // avoid full shift
_Mask <<= 1;
_Mask |= _Bmask;
}
// _Ret is [0, _Mask], _Index - 1 <= _Mask, return if unbiased
if (_Ret / _Index < _Mask / _Index
|| _Mask % _Index == _Udiff(_Index - 1))
return (_Ret % _Index);
}
}
};
}
Приведенный выше код вставлен из stl.Что означает «избегать полной смены»?Я думаю, что сдвиг в два бита можно интегрировать в одну операцию.
_Ret <<= _Bits - 1; // avoid full shift
_Ret <<= 1;
Я изменяю коды следующим образом:
_Ret<<=_Bits;
Что здесь отличается?