使用TR1/dev/random在C++中生成随机数(弹性到<1秒运行)

gny*_*his 6 c++ random random-seed

我希望在C++中生成0到1之间的均匀随机数,其方式不使用标准rand()srand(time(NULL))方法.原因是如果我在我的时钟的同一秒内多次运行应用程序,种子将完全相同并产生相同的输出.

我不想依赖boost或OS /编译器细节.可以假设x86.

似乎另一种方法是使用TR1(我没有C++ 11)并以/dev/random某种方式播种?

现在我有这个,但它仍然time(NULL)用作种子,在1秒内运行不会很好:

#include <iostream> 
#include <tr1/random> 

int main() 
{ 
  std::tr1::mt19937 eng; 
  eng.seed(time(NULL)); 
  std::tr1::uniform_int<int> unif(1, RAND_MAX); 
  int u = unif(eng); 
  std::cout << (float)u/RAND_MAX << std::endl; 
} 
Run Code Online (Sandbox Code Playgroud)

Mys*_*ial 7

根据OP的要求发布:

这仍然是一些特定于编译器的,但仍然适用于几乎所有x86目标编译器:

#ifdef _WIN32

//  Windows
#define rdtsc  __rdtsc

#else

//  For everything else
unsigned long long rdtsc(){
    unsigned int lo,hi;
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return ((unsigned long long)hi << 32) | lo;
}

#endif

int main() 
{ 
  std::tr1::mt19937 eng; 
  eng.seed( rdtsc() );    //  Seed with rdtsc.
  std::tr1::uniform_int<int> unif(1, RAND_MAX); 
  int u = unif(eng); 
  std::cout << (float)u/RAND_MAX << std::endl; 
} 
Run Code Online (Sandbox Code Playgroud)

这里的想法是使用rdtsc循环计数器为随机数生成器播种.

这之所以有效,是因为rdtsc循环计数器以与CPU频率大致(通常相同)的速度迭代.因此,两次调用它返回相同值的可能性非常小 - 从而使其成为RNG的优秀种子.