Modify

Opened 13 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.


Attachments (0)

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

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain jmaurer.
The resolution will be deleted.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.