我需要生成随机数,但希望尽可能宽的范围(至少64位)。我不在乎分布是否完美,所以std::rand()
可以工作,但它只返回一个 int
。我知道 c++11 有一些可以生成任意大小数字的随机数生成能力,但使用起来非常复杂。有人可以发布一个简单的示例,说明如何尽可能简单地使用它获取所需功能(64位或更多随机数),其实现方式与 std::rand()
类似吗?
以下是如何使用C++11的随机数生成器来实现此目的(修改自http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution):
#include <random>
#include <iostream>
int main()
{
/* Initialise. Do this once (not for every
random number). */
std::random_device rd;
std::mt19937_64 gen(rd());
/* This is where you define the number generator for unsigned long long: */
std::uniform_int_distribution<unsigned long long> dis;
/* A few random numbers: */
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << std::endl;
return 0;
}
使用cstdint
中的std::uintmax_t
,而不是unsigned long long
,可以获取最大的整数范围(无需使用实际的大整数库)。
我们可以很容易地将一个随机数生成器引擎封装成类似于 srand/rand 的方法,如下所示:
#include <random>
#include <iostream>
struct MT19937 {
private:
static std::mt19937_64 rng;
public:
// This is equivalent to srand().
static void seed(uint64_t new_seed = std::mt19937_64::default_seed) {
rng.seed(new_seed);
}
// This is equivalent to rand().
static uint64_t get() {
return rng();
}
};
std::mt19937_64 MT19937::rng;
int main() {
MT19937::seed(/*put your seed here*/);
for (int i = 0; i < 10; ++ i)
std::cout << MT19937::get() << std::endl;
}
(就像srand
和rand
一样,此实现不关心线程安全性。)
封装函数非常简单,您可以直接使用引擎。
#include <random>
#include <iostream>
static std::mt19937_64 rng;
int main() {
rng.seed(/*put your seed here*/);
for (int i = 0; i < 10; ++ i)
std::cout << rng() << std::endl;
}
std::mt19937_64::default_seed
被标准化为 5489u
,因此您的示例程序将始终生成相同的输出序列。 - Jeffrey Yasskinsrand()
中一样,你需要提供自己的种子才能获得不同的随机数序列。 - kennytm不是C++11,但足够简单
((unsigned long long)rand() << 32) + rand()
在这里我们将int64生成为两个int32的部分
正如JasonD
所指出的那样,它假设rand()
生成32位整数。可以使用异或运算符rand() << x
、rand() << (2*x)
、rand() << (3*x)
等来生成rand()
数字中产生的位数小于等于x
的数字。这也应该没问题。
RAND_MAX
来确定这一点。 - user152949RAND_MAX
为0x7FFF,即15位。 - kkm
sizeof(unsigned)
字节的熵。如果您需要更多,请在mt19937
的构造函数中传递std::seed_seq
,以传递尽可能多的随机字节。 - Jeffrey Yasskinmt19937_64
的输出类型相同,在这种情况下使用uniform_int_distribution
是否有任何理由? - HammeIAmuniform_int_distribution
,因为梅森旋转器本身就会努力产生均匀分布。 - jogojapan