Random generation with uniform_real in C++ tr1

I spent another hour or so on something annoying this afternoon.Namely, how to get c++ to generate correct random numbers.  A while back, I used the Boost library to generate uniformly distributed random numbers between 0 and 1 (probably) thusly:

tr1ns::mt19937 sparfun_rand;

void sf_srand(unsigned long seed) { sparfun_rand.seed(seed); }

double sf_rand(double min, double max) {
 tr1ns::uniform_real<double> dist(min,max);
 return dist(sparfun_rand);
}

Unfortunately, the function sf_rand(0.,1.) has a fairly overt problem on some versions of g++: it doesn’t return a number between 0 and 1.  It seems as if this is a well known g++ issue, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40331.  I think I fixed this a while back, but then ran into the same issue with some old code today.  Suffice it to say, it’s time to fix it once and for all.  Here are a few functions that have the correct behavior:

See the gist: random functions in c++ tr1

One of the reasons I’m writing this entry is that I couldn’t find any useful advise when I searched today.  Hopefully this post will save someone a few moments.

References

This entry was posted in Code. Bookmark the permalink.

2 Responses to Random generation with uniform_real in C++ tr1

  1. Song Gao says:

    Hey dude, have you finally figured it out?

    I am also experiencing this problem today and I just found out that if you use c++0x instead tr1, the uniform_real_distribution will generate real numbers properly.

    Mine GCC version is 4.6.2. You will need -std=c++0x as a compiler option in order to add support for c++0x.

  2. Jason Fritz says:

    Thanks David! You achieved your goal of “saving someone a few moments”🙂 I stumbled across this totally by accident while searching for how to generate a random double with TR1. I didn’t know there was a bug (or unexpected behavior) before seeing this.

    FYI, to save someone else a few minutes, the g++ people think this is more of a misuse of the TR1 API than a bug. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44653

    The solution is to add a “variate_generator” to your code which does the necessary magic. Here is sample code from the above bugzilla reference:

    int main()
    {
    typedef std::mt19937 eng_t;
    typedef std::uniform_real dist_t;
    typedef std::variate_generator gen_t;
    eng_t eng;
    dist_t dist(0.0, 1.0);
    gen_t gen(eng, dist);

    std::cout << gen() << std::endl;
    return 0;
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s