我很惊讶地看到这个程序的输出:
#include <iostream>
#include <random>
int main()
{
std::mt19937 rng1;
std::mt19937 rng2;
std::uniform_real_distribution<double> dist;
double random = dist(rng1);
rng2.discard(2);
std::cout << (rng1() - rng2()) << "\n";
return 0;
}
是0
- 即std::uniform_real_distribution
使用两个随机数来生成[0,1]范围内的随机double
值。我认为它只会生成一个并重新缩放。在考虑之后我想这是因为std::mt19937
产生32位整数,而double是这个大小的两倍,因此不够“随机”。
问题:如何一般性地找出这个数字,即随机数生成器和浮点类型是否是任意类型?
编辑:我刚注意到我可以使用std::generate_canonical
代替,因为我只对[0,1)的随机数感兴趣。不确定这是否有所作为。
答案 0 :(得分:2)
对于template<class RealType, size_t bits, class URNG> std::generate_canonical
,标准(第27.5.7.2节)明确定义了统一随机数生成器(URNG)的调用次数
max(1,b / log_2 R),
其中b是RealType尾数中位数的最小值,以及赋予generate_canonical作为模板参数的位数。
R是URNG可以返回(URNG::max()-URNG::min()+1)
的数字范围。
但是,在你的例子中,这不会有任何区别,因为你需要2次调用mt19937来填充双尾数的53位。
对于其他发行版,该标准没有提供通用的方法来获取有关URNG必须生成多少数量以获得一个分布数的任何信息。
原因可能是,对于某些分发,生成单个分发号码所需的统一随机数不是固定的,并且可能因呼叫而异。一个例子是std::poisson_distribution
,它通常被实现为一个循环,在每次迭代中绘制一个统一的随机数,直到这些数字的乘积达到某个阈值为止(参见例如implementation of the GNU C++ library(第1523行) -1528))。