5,442,164 members and growing! (16,868 online)
Email Password   helpLost your password?
General Programming » Algorithms & Recipes » General     Intermediate License: The Code Project Open License (CPOL)

Simple Random Number Generation

By John D. Cook

A simple random number generator in C#
C# 2.0, C#, Windows, .NET, .NET 2.0, Dev

Posted: 11 Apr 2008
Updated: 14 Apr 2008
Views: 8,761
Bookmarked: 20 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
16 votes for this Article.
Popularity: 5.17 Rating: 4.29 out of 5
2 votes, 12.5%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
5 votes, 31.3%
4
9 votes, 56.3%
5
SimpleRNG console test program screen shot

Introduction

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.

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.

Background

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 + 1).
    // The result is strictly between 0 and 1.
    return u * 2.328306435996595e-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. 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.

History

  • 11th April, 2008: Initial post
  • 13th April, 2008: Revised article to explain why this generator might be preferable to the built-in generator

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

John D. Cook


I am a software developer and very applied mathematician working for M. D. Anderson Cancer Center in Houston, TX.

Check out my home page or my blog The Endeavour.


Company: M. D. Anderson Cancer Center
Location: United States United States

Other popular Algorithms & Recipes articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 20 of 20 (Total in Forum: 20) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralI'd like some more!memberKEL314:55 24 Aug '08  
GeneralRe: I'd like some more!memberJohn D. Cook17:27 24 Aug '08  
GeneralRe: I'd like some more!memberKEL36:36 25 Aug '08  
Generalwhen both seeds are 0memberPink Li1:56 10 Jun '08  
Generalwhy bother??memberyassir hannoun15:03 11 Apr '08  
GeneralRe: why bother??memberaxelriet16:17 11 Apr '08  
GeneralRe: why bother??memberyassir hannoun16:28 11 Apr '08  
GeneralRe: why bother?? [modified]memberJohn D. Cook17:02 11 Apr '08  
GeneralRe: why bother??mvpJohn Simmons / outlaw programmer4:53 1 May '08  
GeneralI'll stick with what's built-inmemberPIEBALDconsult14:18 11 Apr '08  
GeneralRe: I'll stick with what's built-inmembercp987615:09 11 Apr '08  
GeneralRe: I'll stick with what's built-inmemberPIEBALDconsult15:30 11 Apr '08  
GeneralRe: I'll stick with what's built-inmembercp987617:50 11 Apr '08  
Generaluse it for monte carlo!memberMSE-iT3:44 12 Apr '08  
GeneralRe: I'll stick with what's built-inmemberJeffrey Sax10:11 27 Jun '08  
AnswerRe: I'll stick with what's built-in [modified]memberKEL314:38 24 Aug '08  
GeneralRe: I'll stick with what's built-inmemberPIEBALDconsult12:52 25 Aug '08  
GeneralRe: I'll stick with what's built-inmemberKEL38:44 26 Aug '08  
GeneralSetSeedFromSystemTime() bad ideamemberRobert Kozak13:56 11 Apr '08  
GeneralRe: SetSeedFromSystemTime() bad ideamemberMSE-iT3:12 12 Apr '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 14 Apr 2008
Editor: Sean Ewington
Copyright 2008 by John D. Cook
Everything else Copyright © CodeProject, 1999-2008
Web18 | Advertise on the Code Project