C++11 случайных чисел
Мне нужно генерировать случайные числа, но из максимально широкого диапазона (не менее 64 бит). Мне все равно, если распределение идеально, так std::rand()
будет работать, но это только возвращает int
, Я понимаю, что C++11 имеет некоторую возможность генерирования случайных чисел, которая может дать число любого размера, но очень сложна в использовании. Может кто-нибудь опубликовать простой пример того, как его использовать настолько просто, насколько это возможно, чтобы описанные функциональные возможности (64-битные или более случайные числа) были как можно более простым способом (например, std::rand()
)?
3 ответа
Вот как использовать генерацию случайных чисел в 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;
}
Вместо unsigned long long
Вы могли бы использовать std::uintmax_t
от cstdint
получить максимально возможный диапазон целых чисел (без использования реальной библиотеки больших целых чисел).
Мы могли бы легко обернуть механизм генератора случайных чисел в 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;
}
Не C++11, но достаточно просто
((unsigned long long)rand() << 32) + rand()
Здесь мы генерируем две части int64 как int32
Как JasonD
указал, что предполагается, что rand()
генерировать 32-битное целое число Это может быть вызвано XORrand() << x
, rand() << (2*x)
, rand() << (3*x)
и т. д., где x
<= биты генерируются rand()
number`. Это тоже должно быть хорошо.