2012-12-23 102 views
18

我需要生成隨機數,但是從儘可能寬的範圍(至少64位)生成。我不在乎分發是否完美,因此std::rand()可以使用,但它只返回int。我知道C++ 11有一些隨機數生成功能,可以給出任意大小的數字,但使用起來非常複雜。有人可以發佈一個簡單的例子,說明如何儘可能簡單地使用它(例如std::rand())以儘可能簡單地獲得所描述的功能(64位或更多的隨機數)?C++ 11個隨機數

回答

30

這就是如何使用C++ 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_tcstdint,以獲得最大可能的整數範圍(不使用實際的大整數庫)。

+1

這對於幾乎所有的用途都有很大的好處,但是請注意,它只給出種子的'sizeof(無符號)'字節的熵。如果您需要更多,可以將'[std :: seed_seq'](http://en.cppreference.com/w/cpp/numeric/random/seed_seq)傳遞給'mt19937'的構造函數以通過儘可能多的隨機字節。 –

4

不是C + + 11,但很容易的

((unsigned long long)rand() << 32) + rand()在這裏,我們生成的Int64的兩個部分INT32的

由於JasonD指出,它假定rand()產生32位整數。這可能是異或 rand() << x,rand() << (2*x),rand() << (3*x)等,其中x < =位的生成rand()號碼。它應該也可以。

+12

假定rand()實際上返回一個32位數字。如果不是15位,它可能只有31位。 – JasonD

+1

@JasonD是的,@RiaD應該檢查'RAND_MAX'來確定這一點。 – 2014-01-03 11:02:43

+0

在Microsoft CL下,直到目前的19.x,RAND_MAX是0x7FFF或15位。 – kkm

12

我們可以很容易地換一個隨機數發生器引擎進入函數srand /蘭特樣的方法是這樣的:

#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; 
} 

(像srandrand,這個實現不關心線程安全的。)

包裝函數是如此微不足道,你可以直接使用引擎。

#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; 
} 
+2

不幸的是,'std :: mt19937_64 :: default_seed'被標準化爲'5489u',所以你的示例程序將總是產生相同的輸出序列。 –

+4

@JeffreyYasskin:是的。就像在srand()中一樣,你需要提供你自己的種子來獲得一個獨特的隨機序列。 – kennytm