2013-12-15 121 views
5

我在嘗試使用std::generate_canonical時遇到了問題。從我的閱讀cpp-reference.com,我期望std::generate_canonical生成範圍[0,1)中的數字。 但是,在最新的MSVC 2012(未安裝CTP)上,std::generate_canonical生成的數字全部爲10^28(見下文)。的確,Microsoft's documentation沒有提及std::generate_canonical生成數字的範圍。如何使用std :: generate_canonical生成範圍[0,1)內的隨機數?

Microsoft是否不符合此處的標準?或者是標準缺陷,它對std::generate_canonical的行爲模糊不清?在第二種情況下,我將如何編寫代碼以生成範圍[0,1)內的隨機浮點數?

請考慮下面的示例代碼,我嘗試使用std::generate_canonical。輸出

#include <random> 
#include <limits> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    std::random_device rd; 
    // seed with true source of randomness 
    std::mt19937 _rng_generator(rd()); 

    for(int n=0; n<10; ++n) 
     std::cout << std::generate_canonical<double,std::numeric_limits<double>::digits>(_rng_generator) << ' '; 

    return EXIT_SUCCESS; 
} 

例子,我得到:
4.85267e+028 2.76741e+028 3.17392e+028 5.84136e+028 1.0037e+028 4.87202e+028 2.53834e+028 4.233e+028 6.43922e+028 2.30694e+028

更新: 我以前已報告的錯誤來Microsoft Connect。該錯誤現已得到修復,修復程序將包含在MSVC 2014 RTM中。

+0

我使用G ++ 4.8在Linux中編譯了它,它在[0,1)範圍內生成了10個隨機數。我不知道微軟對你做了什麼。 –

+2

Visual Studio 2013也會生成僞造值。 [uniform_real_distribution](http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution)可能適用於你所需要的。 –

+0

@RetiredNinja。事實上,使用[uniform_real_distribution](http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution)將是現在的解決方案。 –

回答

6

26.5.7.2功能模板generate_canonical [rand.util.canonical]

與本節 26.5.7.2描述的模板實例化的每個功能映射所提供的均勻隨機數的一個或多個調用的結果發生器g到指定 的一個成員RealType使得,如果值g i加g產生均勻分佈 ,實例化的結果tj,0≤tj < 1,是 儘可能均勻分配,如下所述。

template<class RealType, size_t bits, class URNG> 
RealType generate_canonical(URNG& g); 

此外,標準介紹,這個函數返回s/rk,其中
S
R

所以,這個功能應該返回一個值從零到一。我認爲,微軟的實施在這裏是錯誤的。

+1

感謝,報告[Microsoft連接]中的錯誤(https://connect.microsoft.com/VisualStudio/feedback/details/811611/std-generate-canonical-does-not-generate-random-number-in-range-0 -1#) –

-4

下面是MSDN文檔:

http://msdn.microsoft.com/en-us/library/ee462289.aspx

下面是相應的原型:

template<class RealType, 
    size_t bits, 
    class Engine> 
    RealType generate_canonical(Engine& gen); 

這裏是一個完整的例子:

http://msdn.microsoft.com/en-us/library/bb982398.aspx

// cl.exe /EHsc /nologo /W4 /MTd 
#include <algorithm> 
#include <array> 
#include <iostream> 
#include <ostream> 
#include <random> 
#include <string> 
#include <vector> 
using namespace std; 

template <typename C> void print(const C& c) { 
    for (const auto& e : c) { 
     cout << e << " "; 
    } 

    cout << endl; 
} 

void test(unsigned int seed) { 
    cout << "Seed: " << seed << endl; 

    mt19937 engine(seed); 

    uniform_int_distribution<int> dist(-3, 5); 

    vector<int> v; 

    for (int i = 0; i < 30; ++i) { 
     v.push_back(dist(engine)); 
    } 

    cout << "Randomized vector: "; 
    print(v); 

    array<string, 26> arr = { { "H", "He", "Li", "Be", "B", "C", "N", "O", "F", 
     "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", 
     "Ti", "V", "Cr", "Mn", "Fe" } }; 

    shuffle(arr.begin(), arr.end(), engine); 

    cout << "Randomized array: "; 
    print(arr); 
} 

int main() { 
    cout << "--" << endl; 

    test(12345); 

    cout << "--" << endl; 

    random_device rd; 

    test(rd()); 
} 
+2

這就是原始問題中給出的鏈接。這並沒有回答爲什麼MSVC++沒有在期望的範圍[0,1]中產生值。 –

+4

好吧,我看到你的編輯有一個精心設計的例子,但仍然沒有解釋爲什麼'generate_canonical'沒有產生預期的結果。你的例子甚至不使用'generate_canonical'。你在閱讀我的同一個問題嗎? –

相關問題