Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A C# Mersenne Twister class

0.00/5 (No votes)
5 Oct 2003 1  
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