Opened 14 years ago

Closed 9 years ago

#351 closed Bugs (fixed)

Diff in state of mersenne_twister gen between GCC3.41 & CW9

Reported by: toth21 Owned by: jmaurer
Milestone: Component: random
Version: None Severity:
Keywords: Cc:

Description

I have found a bug with the mersenne_twister random 
number generator class, where results when calling for a 
random number vary between codewarrior 9.0 and gcc 
3.4.1 with boost 1.31.0.

A simple example is shown below:

#include <boost/random/mersenne_twister.hpp> 
//for mt11213b

typedef boost::mt11213b     base_generator_type;

class foo
{
 public:
  foo(const base_generator_type gen):m_gen(gen)
  {}

  ~foo(void) {}

  rand_type operator() ( void )
  {
   const float x = m_gen();

   return x;
  }

 private:

  base_generator_type m_gen;
}

int main(void)
{

 base_generator_type gen( (uint32_t) 2000);  
//seed is not important

 foo f(gen);

 cout << "Random result is " << f() << endl;
}

The resulting numbers will be different between 
codewarrior 9.0 running on windows (xp or 2000) and 
gcc 3.4.1 running on Suse linux 7.3.(Hope that is enough
info).

I tracked the cause of the bug down to class 
initialization. In the case of CW9.0, the compiler when 
constructing a foo, will use a mersenne_twister copy 
ctor when initializing m_gen, while in the case of
gcc 3.4.1 it will choose the following in the .hpp file

  template<class Generator>
  explicit mersenne_twister(Generator & gen) { seed
(gen); }

therefore using the provided generator as a seed to the 
new generator rather than just copying its state, even 
though no template parameter is provided.

Anyways I will leave it up to the more informed to decide 
which is more desirable/proper; however, this is a fairly 
nasty bug at the moment as you can not reproduce 
results between these two platforms when using this 
random number generator for your random numbers.


Change History (4)

comment:1 Changed 13 years ago by jmaurer

Logged In: YES 
user_id=53943

Thank you for the bug report. Unless there is a typo, this
constructor appears to always require a copy of "gen"?
 foo(const base_generator_type gen)

If you want to avoid binding to the Generator& constructor
and use the copy constructor instead, you should make sure
to convert "gen" to an rvalue (e.g., by using a
static_cast<const base_generator_type>(...)) before
initializing m_gen. (untested idea).

comment:2 Changed 13 years ago by jmaurer

Logged In: YES 
user_id=53943

Independent of the boost.random implications, it worries me
that two compilers choose two different overloads. That
Should Not Happen (tm). Could you try to come up with a
short example not depending on any libraries that shows the
difference so that Metrowerks and GCC can have a look at it
who is right? If you do it in the next 2 days, I can discuss
it with the compiler authors here at the ISO C++ meeting.

comment:3 Changed 13 years ago by jmaurer

Logged In: YES 
user_id=53943

See issue 4.40 in the C++ committee's library TR issue list.

comment:4 Changed 9 years ago by Steven Watanabe

Resolution: Nonefixed
Status: assignedclosed

(In [53699]) Fix overload resolution for generator constructors/seed. Fixes #351. Fixes #2424. Fixes #2887

Note: See TracTickets for help on using tickets.