Introduction
Before we dive into the details of the System.Random class, we should talk about randomness in discrete mathematics. The two most common scenarios for generating random numbers are generating integers uniformly between 1 and n and generating real numbers uniformly between 0 and 1. Most random-number-generation algorithms are not influenced by the outside universe; they are inherently pseudorandom: predictable and following a pattern (ideally not an obvious one). You should keep in mind the following two statements on pseudorandomness made by respected computer science masters.
- Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. - John Von Neumann (1951).
- Random number generators should not be chosen at random. - Donald Knuth (1986).
Let's go back to our main focus now. We use the System.Random class to produce a random number. System.Random can return both decimal and integer random numbers. In addition, System.Random by design can seed its random number generator with a random value derived from the computer system clock.
System.Randomrnd=newSystem.Random();
You can initialize the seed with any Int32 value on demand at times when the system clock is not fast enough to refresh or when you need to synchronize your random number generators across a network. This is also the common use of a seed to synchronize two random number generators.
System.Randomrnd=newSystem.Random((int)DateTime.Now.Ticks);
The Random class includes a series of methods allowing you to retrieve the next number produced by the random number generator. The NextDouble method returns a double random number between 0.0 and 1.0. The Next method returns an integer random number between two integer values. The NextBytes method fills the elements of a specified array of bytes with random numbers. The NextDouble, Next, and NextBytes methods are instance methods; therefore, you must instantiate a System.Random object before using them.
The Next() method has three overloads
// A positive random number
public virtual int Next();
// A positive random number less than the specified maximum
public virtual int Next(int max);
// A random number within a specified range
public virtual int Next(int min, int max);
// You can use the Next method overloads as shown in Listing 21.37.
// Listing 21.37: Using the Next Property
// Any valid integer random number
Int32 dbl1 = rnd.Next();
// An integer between 0 and UpperBound where UpperBound + 1 >= 0
Int32 dbl1 = rnd.Next(UpperBound + 1);
// An integer between LowerBound and UpperBound where UpperBound + 1 >= 0
// and LowerBound <= UpperBound + 1
Int32 dbl1 = rnd.Next(LowerBound, UpperBound + 1);
Using the NextDouble method of the Random class produces the next pseudorandom double value that is greater than 0.0 and less than 1.0.
Doubledbl1=rnd.NextDouble();
The NextBytes method of the Random class produces an array of random bytes with values ranging from 0 to MaxValue (MaxValue = 255).
Byte[]mybytes=newByte[5];
//mybytesisfilledwith5bytesofrandomdata
rnd.NextBytes(mybytes);
The program in Listing 21.38 generates unique integer random numbers in the ranges that you send to the application and then displays them on the console.
Listing 21.38: Generating Unique Random Numbers with Next(Int32, Int32)
using System;
class TestRandom
{
public static void Main(string[] args)
{
int intNo;
if (args.Length == 0)
{
Console.WriteLine("Please enter a parameter, e.g., unique5");
return;
}
else
{
intNo = Int32.Parse(args[0]);
if (intNo < 1)
{
// Check to see if the user has entered a value >= 1
// because my LowerBound is hardcoded to 1
Console.WriteLine("Enter a value greater than or equal to 1");
return;
}
}
UniqueRandom generateIt = new UniqueRandom();
generateIt.CreateRandom(intNo);
}
}
class UniqueRandom
{
public void CreateRandom(int passedIntNo)
{
int LowerBound = 1;
int UpperBound = passedIntNo;
bool firstTime = true;
int starti = 0;
int[] varArray;
varArray = new int[UpperBound];
// Random Class used here
Random randomGenerator = new Random(DateTime.Now.Millisecond);
do
{
int nogenerated = randomGenerator.Next(LowerBound, UpperBound + 1);
// Note: randomGenerator.Next generates no. to UpperBound-1 hence +1
// I got stuck at this point and had to use the debugger.
if (firstTime) // if (firstTime == true)
{
varArray[starti] = nogenerated;
// we simply store the nogenerated in varArray
firstTime = false;
starti++;
}
else // if (firstTime == false)
{
bool duplicateFlag = CheckDuplicate(nogenerated, starti, varArray);
// call to check in array
if (!duplicateFlag) // duplicateFlag == false
{
varArray[starti] = nogenerated;
starti++;
}
}
} while (starti < UpperBound);
PrintArray(varArray); // Print the array
}
public bool CheckDuplicate(int newRandomNum, int loopCount, int[] functionArray)
{
bool tempDuplicate = false;
for (int j = 0; j < loopCount; j++)
{
if (functionArray[j] == newRandomNum)
{
tempDuplicate = true;
break;
}
}
return tempDuplicate;
}
// PrintArray
public static void PrintArray(Array arr)
{
Console.Write("{");
int count = 0;
int li = arr.Length;
foreach (object o in arr)
{
Console.Write("{0}", o);
count++;
// Condition to check whether ',' should be added in printing array
if (count < li)
Console.Write(",");
}
Console.WriteLine("}");
}
}
Conclusion
Hope this article have helped you in understanding generating random numbers using the System.Random class in C#.