Click here to Skip to main content
Click here to Skip to main content
Go to top

A C# Mersenne Twister class

, 5 Oct 2003
Rate this:
Please Sign up or sign in to vote.
A pseudorandom number generator.

Sample Image - CsharpMersenneTwister.jpg

Introduction

The Mersenne Twister (MT) is a pseudorandom number generator (PRNG) developed by Makoto Matsumoto and Takuji Nishimura[1][2] during 1996-1997. MT has the following merits:

  • It is designed with consideration on the flaws of various existing generators.
  • Far longer period and far higher order of equidistribution than any other implemented generators. (It has been proven that the period is 2^19937-1 and 623-dimensional equidistribution property is assured.)
  • Fast generation. (Although it depends on the system, it is reported that MT is sometimes faster than the standard ANSI-C library in a system with pipeline and cache memory.)
  • Efficient use of the memory.

Credit where it's due

I present a C# class (RandomMT) that encapsulates the work of the creators. I do not take credit for their work; I am merely presenting an object oriented (OO) version of their code that you can simply drop into your game or application. This work has also been derived from CRandomMT. CRandomMT is a C++ wrapper class for the Mersenne Twister, the original Code Project article can be found here. In that article I not only presented a wrapper class for this marvelous pseudorandom number generator but I also discussed the equidistribution of the MT algorithm as well as its speed increases. I will refer you to those articles for the time being as I do not have access to the latest version of TrueTime.

RandomMT

The inspiration for developing a C# version of this class was two-fold.

  1. I wanted to learn C# and what better way to learn a new language than by converting code that you are familiar with and
  2. I’ve been thinking more and more about the future of game development for the PC – specifically using a .NET language.

This thinking resulted in me writing a document that is as much hypothetical as it is factual with respect to game development for the PC in the coming years, those who are interested can find that article here.

Class description

  • RandomMT::RandomMT()

    This is the default CTOR.

  • RandomMT::RandomMT(ULONG seed)

    A constructor that you provide the seed value.

    RandomMT::~RandomMT()

    The DTOR.

  • RandomMT::SeedMT()

    Used to seed or re-seed the random number generator.

  • ULONG RandomMT::RandomInt()

    Returns an unsigned long random number.

  • int RandomMT::RandomRange(int hi, int lo)

    Returns an int random number falling in the range specified.

  • int RandomMT::RollDice(int face, int number_of_dice)

    Returns an int random number for the number of dice specified and the face of the die.

  • int RandomMT::D#(int die_count)

    Returns a simulated roll of the number of dice specified for the die (determined by #). These are just wrappers around RollDice()

  • int RandomMT::HeadsOrTails()

    Returns 0 or 1, used to simulate a coin flip.

Example usage

namespace MersenneTwister
 .
 .
 .
 RandomMT random = new RandomMT();
 int rand_3d6 = random.D6(3);  // roll 3 six sided die
 .
 .
 .

Notes about this implementation

I have held closely to my original C++ implementation as much as possible. The original code used pointer arithmetic which you cannot do in C# and keep the code managed (per MSDN). If someone knows a better approach to this, feel free to let me know.

Update: MT19937

I have updated the code to use the most recent version of the algorithm, MT19937.

Class description

Here is a brief overview of the MT19937 version of the class.

  • ulong genrand_int32()

    generates a random number on [0,0xffffffff]-interval

  • long genrand_int31()

    generates a random number on [0,0x7FFFFFFF]-interval

  • double genrand_real1()

    generates a random number on [0,1]-real-interval

  • double genrand_real2()

    generates a random number on [0,1]-real-interval

  • double genrand_real3()

    generates a random number on [0,1]-real-interval

  • double genrand_real53()

    generates a random number on [0,1] with 53 bit resolution

  • int RandomRange(int lo, int hi)

    returns a random number in the range [hi-lo+1]

Usage

namespace MersenneTwister 
 .
 .
 .
    MT19937 random = new MT19937();
    int rand_d6 = random.RandomRange(1,6);  // roll 1 six sided die
 .
 .
 .

About the demo application

Again, the demo application is fairly lame. This application allows you to roll six 6 sided die and it keeps track of the total number of times that a number has “hit” – you can roll once or 1000 times.

I’ve made use of GDI+ and as I said, I’m learning C# as well as the .NET framework so I may have misused or abused much of GDI+ functionality.

Conclusion

The pursuit of the perfect PRNG is an ongoing effort that eludes computer scientists and mathematicians alike. The Mersenne Twister is generally considered to be fast, small and provides equal distribution. C# is an exciting language and I am looking forward to learning and coding with it in the coming future.

Thanks

Thanks go out to Makoto Matsumoto and Takuji Nishimura for creating the algorithm.

References

  • [1] "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator", M. Matsumoto and T. Nishimura, ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30.
  • [2] Mersenne Twister: A random number generator

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Dave Loeser
Web Developer
United States United States
Dave has been programming for the past 20+ years first on a variety of platforms and operating systems using various languages. As a hobbyist Dave cut his teeth on the Commodore Pet and the 64 coding in basic and then moving to 6502 ASM. Dave moved to the Amiga using 68000 ASM and then C. His knowledge of the C language offered the stepping stone for him to make his hobby his profession taking a position coding C on an AIX Unix platform. Since then he has worked on many flavors of Unix, QNX, Windows (3.11 – present), and has been coding games for his Pocket PC in his spare time.
 
Dave lives in Indiana with his two teenage daughters and two cats.

Comments and Discussions

 
GeneralBUG Pinmemberjawadjee19-May-07 7:37 
GeneralRe: BUG PinmemberRussellSprouts9-Jul-09 5:32 
GeneralEliminating distributional bias [modified] PinmemberMax Topley8-May-07 11:38 
GeneralIncrease performance PinmemberStefan Troschütz13-Aug-06 5:42 
QuestionDid anyone look at the sample project? PinmemberTreBorg20037-Oct-03 6:37 
Generalsevere bugs Pinmemberinterj7-Oct-03 2:38 
GeneralRe: severe bugs PinmemberDave Loeser7-Oct-03 5:10 
GeneralAnother implementation PinmemberJonathan de Halleux6-Oct-03 20:09 
GeneralGood Point PinmemberNormski6-Oct-03 21:02 
GeneralYou lost the race :) PinmemberJonathan de Halleux7-Oct-03 1:57 
GeneralRe: You lost the race :) PinmemberDave Loeser7-Oct-03 5:08 
General... yes but PinmemberJonathan de Halleux7-Oct-03 5:35 
GeneralRe: ... yes but PinmemberDave Loeser7-Oct-03 9:29 
Generalstill behing :) PinmemberJonathan de Halleux8-Oct-03 23:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140905.1 | Last Updated 6 Oct 2003
Article Copyright 2003 by Dave Loeser
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid