Library code snippets

Random Numbers... That Work!

After reading at least a dozen articles on how to generate random numbers, I’m sorry to say that technical writers are still getting it wrong.

Don’t misunderstand me: generating random numbers is actually very easy. You simply create a new instance of the System.Random class, passing in a “seed” value. Then you use the object .Next method to return a fresh value. The problem is that most developers place the new instance of the Random class inside the function that generates the number itself.

This means that, if the function is run a number of times at speed, the “seed” (typically a value based on the number of “ticks” for the current date and time) given to the Random class may be the same each time. Now, the Random class is never truly random and simply runs a formula to “randomize” the next number. Because most developers are declaring a new instance of the class inside the function, it gets created afresh with every single call, follows its same formula with the same seed to generate a random number – and creates one exactly the same as the last! (Until, at least, the tick “seed” value alters).

The trick is to declare the new Random class outside of the function that retrieves the next random number. This way you generate the seed only once and are getting the “randomizer” formula to cycle through its formula and ensure the next chosen number is truly random.
Here’s my code. Note that you no longer have to declare new objects (such as objRandom, here) at the top of your class or module; you can do it just above the function, to aid clarity of code:

Dim objRandom As New System.Random( _
  CType(System.DateTime.Now.Ticks Mod System.Int32.MaxValue, Integer))

Public Function GetRandomNumber( _
  Optional ByVal Low As Integer = 1, _
  Optional ByVal High As Integer = 100) As Integer
  ' Returns a random number,
  ' between the optional Low and High parameters
  Return objRandom.Next(Low, High + 1)
End Function

And here’s how you may use this function in code:

Dim intDiceRoll As Integer
intDiceRoll = GetRandomNumber(1, 6)
MessageBox.Show("You rolled a " & intDiceRoll.ToString)

Comments

  1. 17 Mar 2009 at 15:52
    If you wanted to keep this functionality, but contain everything within the same function, declaringyour random number as static would work too. Public Function GetRandomNumber(Optional ByVal Low as Integer = 1, Optional ByVal High As Integer = 100) As Integer Static objRandom as New Random() Return objRandom.Next(Low, High + 1) End Function
  2. 17 Sep 2008 at 17:22

     thank you sir.

     

    looking for this for looong time already.

  3. 29 Jan 2007 at 05:48
    neat.. btw, do you have the C# version of this? thanks..

  4. 06 Jan 2007 at 17:51
    Yes sir, you're right. Effectively, this procedure really works. Thanks!
  5. 03 Dec 2005 at 21:07
    Very helpful, well explained, cleared up my question.
  6. 01 Jan 1999 at 00:00

    This thread is for discussions of Random Numbers... That Work!.

Leave a comment

Sign in or Join us (it's free).

Karl Moore

Related podcasts

  • xpert to Expert: Inside Concurrent Basic (CB)

    "Concurrent Basic extends Visual Basic with stylish asynchronous concurrency constructs derived from the join calculus. Our design advances earlier MSRC work on Polyphonic C#, Comega and the Joins Library. Unlike its C# based predecessors, CB adopts a simple event-like syntax familiar to VB progr...

Want to stay in touch with what's going on? Follow us on twitter!