how to use std::generate_canonical to generate random number in range [0,1)?

Viewed 1990

I am running into an issue when trying to use std::generate_canonical. From my reading at cpp-reference.com, I expect std::generate_canonical to generate numbers in the range [0,1). However, on an up-to-date MSVC 2012 (CTP not installed), std::generate_canonical generates numbers that are all of the order 10^28 (see below). Indeed, Microsoft's documentation does not mention the range in which std::generate_canonical generates numbers.

Does Microsoft not comply with the standard here? Or is the standard deficient in that it is vague about std::generate_canonical's behavior? In the second case, how would I write code to generate a random floating point number in the range [0,1)?

Please consider the below example code for my attempt at using 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;
}

Example of the output I get:
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

Update: I have previously reported the bug to Microsoft Connect. The bug has now been fixed and the fix will be included in MSVC 2014 RTM.

3 Answers

The cpp reference that you refer to currently says:

"Some existing implementations have a bug where they may occasionally return 1.0 if RealType is float GCC #63176 LLVM #18767. This is LWG issue 2524"

According to the issue, "The problem is that the standard specifies the implementation, and the implementation doesn't work."

The issue was opened on 2015-08-20, a couple of years after you posted this question.

Related