стандарт rand()
функция выдаёт недостаточно большие цифры: мне нужно unsigned long long
из них. Как мы можем получить действительно большие случайные числа? Я пытался изменить простую хэш-функцию, но это слишком большой, бегает слишком долго и никогда не выдает чисел меньше 1e5 !!
Вот портативное решение C99, которое возвращает случайное 64-битное число:
unsigned long long llrand() {
unsigned long long r = 0;
for (int i = 0; i < 5; ++i) {
r = (r << 15) | (rand() & 0x7FFF);
}
return r & 0xFFFFFFFFFFFFFFFFULL;
}
Объяснение: rand()
возвращает целые числа в диапазоне от 0 до RAND_MAX
а также RAND_MAX
гарантируется только 32 767 (15 случайных битов). long long
гарантированно имеет 64 бита, но может быть больше.
Вы можете легко сделать это с std::uniform_int_distribution<unsigned long long>
.
Простой пример кода (взят из Вот, модифицировано для использования unsigned long long
):
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned long long> dis(lowerBorder, upperBorder);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
Обратите внимание, что засевание мерсенового твистера, как здесь сделано для демонстрационных целей, не является идеальным, например, см. Вот.
Если вы хотите просто создать unsigned long long из значения, возвращаемого rand (), и не заботитесь о характеристиках результата, рассмотрите следующую функцию, которая должна быть независимой от версии компилятора и платформы (потому что «магические числа» не используются):
// this header has RAND_MAX value
#include <stdlib.h>
// and this header has ULLONG_MAX
#include <limits.h>
unsigned long long ullrand()
// Produces pseudo-random numbers from 0 to ULLONG_MAX
// by filling all bits of unsigned long long integer number
// with bits of several "small" integer numbers generated by rand()
{
unsigned long long myrndnum = 0; // at the beginning just zero
unsigned long long counter = ULLONG_MAX; // at the beginning we have all bits set as 1
// ... and while at least one bit is still set to 1
while(counter > 0) {
myrndnum = (myrndnum * (RAND_MAX + 1)) + rand(); // fill some bits from rand()
counter /= (RAND_MAX + 1); // decrease number of 1-bits in counter
}
// Return the result
return myrndnum;
}
Но если вам нужна какая-то последовательность случайных чисел с определенными заранее заданными характеристиками, вам следует заглянуть в некоторые конкретные руководства или математические книги. Например. https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html
Вы не просили конкретную ОС, и ответы здесь действительно хорошие, но в Linux (и, вероятно, в других ОС) вы также можете читать со случайного устройства.
Пример:
#include <stdio.h>
#include <assert.h>
#define RANDDEV "/dev/urandom"
unsigned long long bigrand(void) {
FILE *rdp;
unsigned long long num;
rdp = fopen(RANDDEV, "rb");
assert(rdp);
assert(fread(&num, sizeof(num), 1, rdp) == 1);
fclose(rdp);
return num;
}
Написано на мобильном телефоне, возможно, есть ошибки. :П
Вы также можете использовать библиотеку повышения (взято из ссылка на сайт):
#include <ctime> // std::time
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>int main()
{
long long my_min = 1;
long long my_max = 1e5;
boost::mt19937 generator(static_cast<unsigned int>(std::time(0)));
boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
die_gen(generator, boost::uniform_real<> (my_min, my_max));
boost::generator_iterator<boost::variate_generator<boost::mt19937&, boost::uniform_real<> > > die(&die_gen);
std::cout<<"Generated random numbers: \n";
for (int i=0; i <10 ; i++)
{
std::cout<< static_cast<long long>(*die++) << std::endl;
}
return 0;
}
попробуй это:
long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()