1. Technology

How to use random numbers in Visual Basic .NET programs

... and how to interpret the Microsoft documentation.

By

Updated August 31, 2008

Microsoft offers excellent support for random numbers in Visual Basic .NET. The core object Random is a member of that most fundamental .NET namespace System. Visual Basic also provides the Randomize and Rnd functions in Microsoft.VisualBasic.VBMath. For real randomness, System.Security.Cryptography provides the RNGCryptoServiceProvider object.

If this isn't enough, it's not that hard to write routines that create good random numbers yourself. Tim Patrick's Visual Basic 2005 Cookbook shows how to program the "BetterRandom" class which is a step up from the usually 'good enough' pseudo-random numbers provided directly by the Random class in .NET.

But the documentation provided for the Random class leaves a lot to be desired. Here's the code in their documentation.

Dim bytes1(99), bytes2(99) As Byte
Dim rnd1 As New Random()
Dim rnd2 As New Random()

rnd1.NextBytes(bytes1)
rnd2.NextBytes(bytes2)

The point of this code is that, "because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. The ... example illustrates that two Random objects that are instantiated in close succession generate an identical series of random numbers."

In different words, since no parameters are passed to Random(), the current value of the system clock is used instead. And since your computer is a lot faster than the system clock, the same value of the clock is used when two Random() objects are created at almost the same time.

The code made more sense to me (but it does the same thing) when I recoded it this way:

Dim intArray1(99), intArray2(99) As Integer
Dim rnd1 As New Random()
Dim rnd2 As New Random()

For i As Integer = 0 To 99
   intArray1(i) = rnd1.Next()
Next
For i As Integer = 0 To 99
   intArray2(i) = rnd2.Next()
Next

The arrays do end up with exactly the same series of numbers and this illustrates one of the problems with "pseudo" random numbers. This declaration on my machine ...

Dim rnd As New Random(12345)

... will always create this series ...

143337951
150666398
1663795458
1097663221
1712597933
1776631026
... and so forth

So the arrays might be nicely distributed, but they're not exactly 'random'. This fact can be useful sometimes to produce the same 'random' example. But for this reason, it's a good idea to avoid creating the Random object more than once. It's all to easy to generate the same sequence of numbers.

VB.NET also provides the Randomize and Rnd function. Partly because Visual Basic provides both Random and Rnd and they both do about the same thing (but with different syntax), there is a lot of confusion about using them.

Rnd will also generate a random number and as a function, you don't have to declare it; you just use it.

Dim MyRand As Single = Rnd()

Like Random, if you don't initialize it, VB.NET uses the value of the system clock as the seed. But if you choose to initialize it, you can use Randomize. There's no requirement to use Randomize that I know of. (In spite of statements you can find on the web to the contrary.) Repeated calls to Rnd will use the last-generated number as a seed value. So this code works fine to generate a convenient pseudorandom array:

Dim sngArray(99) As Single
For i As Integer = 0 To 99
   sngArray(i) = Rnd()
Next

Since it's a function and not an object, however, Rnd doesn't have methods or properties. As partial compensation, Microsoft coded Rnd so it does different things based on the parameter passed. Here's what Rnd will generate if it is passed a number that is ...

  • Less than zero - The same number every time, using Number as the seed.
  • Greater than zero - The next random number in the sequence.
  • Equal to zero - The most recently generated number.
  • Not supplied - The next random number in the sequence.

So, for example, this code will generate the same number twice.

Dim MyRand As Single = Rnd()
Console.WriteLine(MyRand)
Rnd(0)
Console.WriteLine(MyRand)

The bottom line here is that if you just want something fast for, say, a dice game, use Rnd. But if you need more control but still not cryptographic quality, use the Random object.

If you do need cryptographic quality ... we check that out on the next page.

  1. About.com
  2. Technology
  3. Visual Basic
  4. Using VB.NET
  5. Demystifying Random Numbers - Interpreting the Microsoft Doc

©2014 About.com. All rights reserved.