[英]Getting big random numbers in C/C++
标准rand()
函数给出的数字对我来说还不够大:我需要unsigned long long
整数。 我们如何获得真正的大随机数? 我试图改变一个简单的哈希函数,但它太大 ,时间太长,并且永不会产生哪些小于1E5的数字!
您可以使用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()返回的值中产生长整型且不关心结果的特征,请考虑以下函数,该函数必须是编译器版本和平台无关的(因为未使用“幻数”):
// 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;
}
写在手机上,可能有错误。 :P
您还可以使用boost库(摘自link ):
#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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.