Click here to Skip to main content
11,925,231 members (54,593 online)
Click here to Skip to main content
Add your own
alternative version


161 bookmarked

Simple Random Number Generation

, 26 Jun 2014 Public Domain
Rate this:
Please Sign up or sign in to vote.
A simple random number generator in C#


Random number generation is tricky business. Good random number generation algorithms are tricky to invent. Code implementing the algorithms is tricky to test. And code using random number generators is tricky to test. This article will describe SimpleRNG, a very simple random number generator. The generator uses a well-tested algorithm and is quite efficient. Because it is so simple, it is easy to drop into projects and easy to debug into.

SimpleRNG can be used to generate random unsigned integers and double values with several statistical distributions:

  • Beta
  • Cauchy
  • Chi square
  • Exponential
  • Inverse gamma
  • Laplace (double exponential)
  • Normal
  • Student t
  • Uniform
  • Weibull

Why Not Just Use the .NET Random Number Generator?

For many applications, it hardly matters what random number generator you use, and the one included in the .NET runtime would be the most convenient. However, sometimes it helps to have your own random number generator. Here are some examples.

  1. When debugging, it's convenient to have full access to the random number generator. You may want to examine the internal state of the generator, and it helps if that state is small. Also, it may be helpful to change the generator temporarily, making the output predictable to help debug code that uses the generator.
  2. Sometimes it is necessary to compare the output of programs written in different languages. For example, at my work we often take prototype code that was written in R and rewrite it in C++ to make it more efficient. If both programs use their own library's random number generator, the outputs are not directly comparable. But if both programs use the same algorithm, such as the one used here, the results might be directly comparable. (The results still might not match due to other differences.)
  3. The statistical quality of the built-in generator might not be adequate for some tasks. Also, the attributes of the generator could change without notice when you apply a service pack.


George Marsaglia is one of the leading experts in random number generation. He's come up with some simple algorithms that nevertheless produce high quality output. The generator presented here, SimpleRNG, uses Marsaglia's MWC (multiply with carry) algorithm. The algorithm is mysterious but very succinct. The algorithm passes Marsaglia's DIEHARD battery of tests, the acid test suite for random number generators.

The heart of SimpleRNG is three lines of code. Here is the method that generates uniformly distributed unsigned integers.

private static uint GetUint()
    m_z = 36969 * (m_z & 65535) + (m_z >> 16);
    m_w = 18000 * (m_w & 65535) + (m_w >> 16);
    return (m_z << 16) + m_w;

Here m_w and m_z are unsigned integers, the only member variables of the class. It's not at all obvious why this code should produce quality random numbers, but it does.

The unsigned integer is then turned into a double in the open interval (0, 1). ("Open" means that the end points are not included; the method will not return 0 or 1, only numbers in between.)

public static double GetUniform()
    // 0 <= u < 2^32
    uint u = GetUint();
    // The magic number below is 1/(2^32 + 2).
    // The result is strictly between 0 and 1.
    return (u + 1.0) * 2.328306435454494e-10;

Using the Code

The SimpleRNG class has two seeds. These have default values, or they can be specified by calling SetSeed() with one or two arguments. These arguments must be non-zero; if an argument is zero, it is replaced by the default value. Some may prefer to throw an exception in this case rather than silently fix the problem. There is also an option to set the seed values from the system clock using SetSeedFromSystemTime(). Once the class is initialized, there is only one public method to call, GetUniform().

Points of Interest

The code to test SimpleRNG is more complicated than SimpleRNG itself. The test code included as a demo uses a statistical test, the Kolmogorov-Smirnov test, to confirm that the output of the generator has the expected statistical properties. If this test were applied repeatedly with ideal random input, the test would fail on average once in every thousand applications. This is highly unusual in software testing: the test should fail occasionally! That's statistics for you. Don't be alarmed if the test fails. Try again with another seed and it will most likely pass. The test is good enough to catch most coding errors since a bug would likely result in the test failing far more often. The test code also uses RunningStat, a class for accurately computing sample mean and variance as values accumulate.

Further Reading

For more information on random number generation, particularly on subtle things that can go wrong, see the CodeProject article Pitfalls in Random Number Generation. If you are using C++, see Random number generation using C++ TR1.


  • 11th April, 2008: Initial post
  • 13th April, 2008: Revised article to explain why this generator might be preferable to the built-in generator
  • 30th September, 2008: Added further reading section
  • 4th October, 2008: Fixed two bugs based on reader feedback. Now seeds cannot be 0, and GetUniform cannot return 0.
  • 22nd October, 2008: Added methods for generating normal (Gaussian) and exponential random samples
  • 19th February, 2010: Fixed incompatibility with Marsaglia's MWC algorithm
  • 30th April, 2010: Added methods for new distributions, extended the test code
  • 27th July, 2010: Updated article
  • 6th January, 2011: Updated article and download files
  • 16th March, 2011: Updated article and download files per Craig McQueen‘s comment regarding the lower bits of the core generator


This article, along with any associated source code and files, is licensed under A Public Domain dedication


About the Author

John D. Cook
Singular Value Consulting
United States United States
I am an independent consultant in software development and applied mathematics. I help companies learn from their data to make better decisions.

Check out my blog or send me a note.


You may also be interested in...

Comments and Discussions

QuestionExcellent Pin
YvesDaoust28-Jun-14 1:46
memberYvesDaoust28-Jun-14 1:46 
QuestionSimple it is and works great. good job! Pin
hanyionet26-Jan-14 5:04
memberhanyionet26-Jan-14 5:04 
GeneralVery useful, thanks Pin
Member 104378031-Dec-13 11:24
memberMember 104378031-Dec-13 11:24 
QuestionFor Java? Pin
HC443-Jul-13 18:55
memberHC443-Jul-13 18:55 
QuestionParallel form of Marsaglia Pin
brainsearching22-Apr-13 7:46
memberbrainsearching22-Apr-13 7:46 
QuestionGenerating a sequence of random numbers in parallel Pin
brainsearching22-Apr-13 3:00
memberbrainsearching22-Apr-13 3:00 
QuestionIs there a way to somehow reset the RNG? Pin
Eddie Y Chen24-Oct-12 0:08
memberEddie Y Chen24-Oct-12 0:08 
AnswerRe: Is there a way to somehow reset the RNG? Pin
Eddie Y Chen24-Oct-12 16:03
memberEddie Y Chen24-Oct-12 16:03 
GeneralMy vote of 5 Pin
silleryxu9-Oct-12 0:25
membersilleryxu9-Oct-12 0:25 
GeneralMy vote of 5 Pin
Florian Rappl15-Aug-12 3:54
memberFlorian Rappl15-Aug-12 3:54 
QuestionBug or not? Pin
Member 855191013-Aug-12 11:07
memberMember 855191013-Aug-12 11:07 
AnswerRe: Bug or not? Pin
martinankerl22-Oct-12 2:32
membermartinankerl22-Oct-12 2:32 
GeneralRe: Bug or not? Pin
damon_achey26-Nov-12 13:22
memberdamon_achey26-Nov-12 13:22 
AnswerRe: Bug or not? Pin
KP Lee29-Jun-14 0:24
memberKP Lee29-Jun-14 0:24 
GeneralMy vote of 5 Pin
SamarRizvi11-Jun-12 5:18
memberSamarRizvi11-Jun-12 5:18 
QuestionOverflow error after converting to VB Pin
JimT Utah21-Mar-12 5:37
memberJimT Utah21-Mar-12 5:37 
AnswerRe: Overflow error after converting to VB (Never Mind!) Pin
JimT Utah21-Mar-12 6:20
memberJimT Utah21-Mar-12 6:20 
QuestionQuick C++ port Pin
Tim Deveaux10-Feb-12 10:44
memberTim Deveaux10-Feb-12 10:44 
AnswerRe: Quick C++ port Pin
John D. Cook10-Feb-12 10:57
memberJohn D. Cook10-Feb-12 10:57 
GeneralRe: Quick C++ port Pin
Tim Deveaux10-Feb-12 11:19
memberTim Deveaux10-Feb-12 11:19 
SuggestionBad seeds Pin
Craig McQueen27-Oct-11 16:05
memberCraig McQueen27-Oct-11 16:05 
GeneralRe: Bad seeds Pin
HaBiX20-Jan-13 23:43
memberHaBiX20-Jan-13 23:43 
QuestionUsing the dual parameter seed constructor Pin
GenericJoe23-Oct-11 13:53
memberGenericJoe23-Oct-11 13:53 
AnswerRe: Using the dual parameter seed constructor Pin
John D. Cook23-Oct-11 14:13
memberJohn D. Cook23-Oct-11 14:13 
QuestionPeriod Pin
GenericJoe22-Oct-11 13:36
memberGenericJoe22-Oct-11 13:36 
AnswerRe: Period Pin
John D. Cook22-Oct-11 13:41
memberJohn D. Cook22-Oct-11 13:41 
GeneralRe: Period Pin
GenericJoe23-Oct-11 12:23
memberGenericJoe23-Oct-11 12:23 
AnswerRe: Period Pin
Craig McQueen27-Oct-11 16:00
memberCraig McQueen27-Oct-11 16:00 
GeneralMy vote of 5 Pin
bear_21-Jul-11 21:32
memberbear_21-Jul-11 21:32 
AnswerVery Nice Algorithm Pin
K Vikas25-May-11 19:53
memberK Vikas25-May-11 19:53 
GeneralMy vote of 5 Pin
jim lahey18-Mar-11 2:20
memberjim lahey18-Mar-11 2:20 
GeneralReally excellent [modified] Pin
KenJohnson8-Jan-11 5:57
memberKenJohnson8-Jan-11 5:57 
GeneralRe: Really excellent Pin
John D. Cook8-Jan-11 6:41
memberJohn D. Cook8-Jan-11 6:41 
QuestionBug? Pin
ktk682-Jan-11 0:19
memberktk682-Jan-11 0:19 
AnswerRe: Bug? [modified] Pin
John D. Cook6-Jan-11 17:15
memberJohn D. Cook6-Jan-11 17:15 
QuestionWhy static members? Pin
ktk681-Jan-11 22:45
memberktk681-Jan-11 22:45 
GeneralNeed help using your solution Pin
Kuntal_patel16-Oct-10 22:08
memberKuntal_patel16-Oct-10 22:08 
AnswerRe: Need help using your solution Pin
Craig McQueen27-Oct-11 18:34
memberCraig McQueen27-Oct-11 18:34 
GeneralSimple random number function Pin
_dog2-Sep-10 7:16
member_dog2-Sep-10 7:16 
GeneralVery nice. Gets a 5 Pin
victorbos4-Aug-10 3:26
membervictorbos4-Aug-10 3:26 
GeneralRe: Very nice. Gets a 5 Pin
John D. Cook4-Aug-10 3:57
memberJohn D. Cook4-Aug-10 3:57 
GeneralRe: Very nice. Gets a 5 Pin
victorbos4-Aug-10 4:00
membervictorbos4-Aug-10 4:00 
GeneralRe: Very nice. Gets a 5 Pin
victorbos4-Aug-10 5:14
membervictorbos4-Aug-10 5:14 
GeneralRe: Very nice. Gets a 5 Pin
John D. Cook4-Aug-10 5:59
memberJohn D. Cook4-Aug-10 5:59 
GeneralRe: Very nice. Gets a 5 Pin
victorbos4-Aug-10 7:02
membervictorbos4-Aug-10 7:02 
GeneralRe: Very nice. Gets a 5 Pin
John D. Cook16-Aug-10 6:38
memberJohn D. Cook16-Aug-10 6:38 
GeneralRe: Very nice. Gets a 5 Pin
victorbos21-Aug-10 6:14
membervictorbos21-Aug-10 6:14 
GeneralMy vote of 5 Pin
OnAClearDiskYouCanSeekForever2-Aug-10 20:28
memberOnAClearDiskYouCanSeekForever2-Aug-10 20:28 
GeneralThank you, you have my five. Pin
KenJohnson27-Jul-10 21:45
memberKenJohnson27-Jul-10 21:45 
First I very much appreciate mathematical articles. Second I would really appreciate some more explanation on why GetUint works. Not obvious is definitely an understatement. Can this be extended if one needed random numbers from 1 to n where n could be gargantuan. In particular I want to generate random rational numbers and I would like to have potentially thousands or more digits in the numerator and denominator. If you have any Ideas as to how to make a good random number generator for Rational Numbers - .Net 4.0 version , it would be greatly appreciated.

GeneralRe: Thank you, you have my five. Pin
John D. Cook28-Jul-10 7:44
memberJohn D. Cook28-Jul-10 7:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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 | Terms of Use | Mobile
Web02 | 2.8.151125.3 | Last Updated 26 Jun 2014
Article Copyright 2008 by John D. Cook
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid