C++ C++;避免在钻头操作中完全移位 模板 类从 {//将骨灰盒包装为RNG 公众: 显式_Rng_from_urng(_urng&_Func) :_Ref(_Func),_Bits(CHAR_BIT*sizeof(_Udiff)),_Bmask(_Udiff(-1)) {//从URNG构造 对于(;(\u Urng::max)(-(\u Urng::min)(>=1) --_比特; } _Diff运算符()(_Diff_索引) {//adapt{u将闭合范围调整为[0,\u索引) 对于(;;) {//尝试一个随机值样本 _Udiff_Ret=0;//随机位 _Udiff _Mask=0;//2^N-1,_Ret在[0,_Mask]之内 而(_掩码从左向右分组
shift operators>从左向右分组 移位表达式: 加法表达式 移位表达式>加法表达式 操作数应为整数或无范围枚举类型,并执行整数提升。结果类型为提升后的左操作数。如果右操作数为负,或大于或等于提升后的左操作数的位长度,则行为未定义。 7.6.7轮班操作员C++ C++;避免在钻头操作中完全移位 模板 类从 {//将骨灰盒包装为RNG 公众: 显式_Rng_from_urng(_urng&_Func) :_Ref(_Func),_Bits(CHAR_BIT*sizeof(_Udiff)),_Bmask(_Udiff(-1)) {//从URNG构造 对于(;(\u Urng::max)(-(\u Urng::min)(>=1) --_比特; } _Diff运算符()(_Diff_索引) {//adapt{u将闭合范围调整为[0,\u索引) 对于(;;) {//尝试一个随机值样本 _Udiff_Ret=0;//随机位 _Udiff _Mask=0;//2^N-1,_Ret在[0,_Mask]之内 而(_掩码从左向右分组,c++,bit,C++,Bit,shift operators>从左向右分组 移位表达式: 加法表达式 移位表达式>加法表达式 操作数应为整数或无范围枚举类型,并执行整数提升。结果类型为提升后的左操作数。如果右操作数为负,或大于或等于提升后的左操作数的位长度,则行为未定义。 7.6.7轮班操作员 shift operators>从左向右分组 移位表达式: 加法表达式 移位表达式>加法表达式 操作数应为整数或无范围枚举类型,并执行整数提升。结果类型为提升后的左操作数。如果右操作数为负,或大于或等于提升后的左操作数的位长度,则行为
也就是说,如果
\u位
等于sizeof(\u Udiff)*CHAR\u位
,如果构造函数中没有输入for循环,可能会发生这种情况,那么移位被分为两个移位,以避免\u位
等于sizeof(\u Udiff)时出现未定义的行为*字符位
,如果未输入构造函数中的for循环,则可能发生这种情况。
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);
}
}
};
}
_Ret <<= _Bits - 1; // avoid full shift
_Ret <<= 1;
_Ret<<=_Bits;