Подтвердить что ты не робот

С++ 11 случайных чисел

Мне нужно генерировать случайные числа, но из максимально широкого диапазона (по крайней мере, 64 бит). Меня не волнует, что дистрибутив идеален, поэтому std::rand() будет работать, но он возвращает только int. Я понимаю, что С++ 11 имеет некоторую возможность генерации случайных чисел, которая может дать любой номер размера, но очень сложна в использовании. Может ли кто-нибудь опубликовать простой пример того, как использовать его как можно проще, чтобы получить описанную функциональность (64 бит или более случайных чисел) максимально простым способом (например, std::rand())?

4b9b3361

Ответ 1

Для этого используется генерация случайных чисел С++ 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 для получения максимально возможного целочисленного диапазона (без использования реальной библиотеки с большим целым числом).

Ответ 2

Мы могли бы легко обернуть механизм генератора случайных чисел в 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;
}

Ответ 3

Не С++ 11, но достаточно легкий

((unsigned long long)rand() << 32) + rand() Здесь мы генерируем две части int64 как int32

Как указывал JasonD, он предполагает, что rand() генерирует 32-битное целое число. Это может быть xor rand() << x, rand() << (2*x), rand() << (3*x) и т.д., где x <= бит в генерации с помощью rand() number`. Также должно быть хорошо.