标准rand()
函数给出的数字对我来说不够大:我需要unsigned long long
。我们如何获得非常大的随机数?我尝试修改一个简单的哈希函数,但它太大了,运行时间太长,而且永远不会产生小于 1e5 的数字!
6 回答
您可以使用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';
}
请注意,此处为演示目的所做的 mersenne twister 播种并不完美,例如,请参见此处。
这是一个可移植的 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 位,但可能更大。
如果您只想从 rand() 返回的值生成 unsigned long long 并且不关心结果的特征,请考虑以下必须是编译器版本和平台独立的函数(因为不使用“幻数”):
// 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;
}
写在手机上,可能有bug。:P
您还可以使用 boost 库(取自链接):
#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()