Represents a pseudo-random number generator, which is a device that produces a sequence of numbers that meet certain statistical requirements for randomness.
To browse the .NET Framework source code for this type, see the Reference Source.
Assembly: mscorlib (in mscorlib.dll)
Determines whether the specified object is equal to the current object.(Inherited from Object.)
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.(Inherited from Object.)
Serves as the default hash function. (Inherited from Object.)
Returns a non-negative random integer.
Returns a non-negative random integer that is less than the specified maximum.
Returns a random integer that is within a specified range.
Fills the elements of a specified array of bytes with random numbers.
Returns a random floating-point number that is greater than or equal to 0.0, and less than 1.0.
Returns a random floating-point number between 0.0 and 1.0.
Returns a string that represents the current object.(Inherited from Object.)
To view the .NET Framework source code for this type, see the Reference Source. You can browse through the source code online, download the reference for offline viewing, and step through the sources (including patches and updates) during debugging; see instructions.
Pseudo-random numbers are chosen with equal probability from a finite set of numbers. The chosen numbers are not completely random because a mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. The current implementation of theclass is based on a modified version of Donald E. Knuth's subtractive random number generator algorithm. For more information, see D. E. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-Wesley, Reading, MA, third edition, 1997.
To generate a cryptographically secure random number, such as one that's suitable for creating a random password, use the RNGCryptoServiceProvider class or derive a class from System.Security.Cryptography.RandomNumberGenerator.
In this topic:
Instantiating the random number generator
Avoiding multiple instantiations
The System.Random class and thread safety
Generating different types of random numbers
Substituting your own algorithm
How do you use System.Random to…
Retrieve the same sequence of random values
Retrieve unique sequences of random values
Retrieve integers in a specified range
Retrieve integers with a specified number of digits
Retrieve floating-point values in a specified range
Generate random Boolean values
Generate random 64-bit integers
Retrieve bytes in a specified range
Retrieve an element from an array or collection at random
Retrieve a unique element from an array or collection
You instantiate the random number generator by providing a seed value (a starting value for the pseudo-random number generation algorithm) to a Random class constructor. You can supply the seed value either explicitly or implicitly:
The Random(Int32) constructor uses an explicit seed value that you supply.
The Random() constructor uses the system clock to provide a seed value. This is the most common way of instantiating the random number generator.
If the same seed is used for separateobjects, they will generate the same series of random numbers. This can be useful for creating a test suite that processes random values, or for replaying games that derive their data from random numbers. However, note that objects in processes running under different versions of the .NET Framework may return different series of random numbers even if they're instantiated with identical seed values.
To produce different sequences of random numbers, you can make the seed value time-dependent, thereby producing a different series with each new instance of Random(Int32) constructor can take an Int32 value based on the number of ticks in the current time, whereas the parameterless Random() constructor uses the system clock to generate its seed value. However, because the clock has finite resolution, using the parameterless constructor to create different objects in close succession creates random number generators that produce identical sequences of random numbers. The following example illustrates how two objects that are instantiated in close succession generate an identical series of random numbers. On most Windows systems, objects created within 15 milliseconds of one another are likely to have identical seed values.. The parameterized
To avoid this problem, create a singleobject instead of multiple objects.
Initializing two random number generators in a tight loop or in rapid succession creates two random number generators that can produce identical sequences of random numbers. In most cases, this is not the developer's intent and can lead to performance issues, because instantiating and initializing a random number generator is a relatively expensive process.
Both to improve performance and to avoid inadvertently creating separate random number generators that generate identical numeric sequences, we recommend that you create oneobject to generate many random numbers over time, instead of creating new objects to generate one random number.
However, theclass isn't thread safe. If you call methods from multiple threads, follow the guidelines discussed in the next section.
Instead of instantiating individualobjects, we recommend that you create a single instance to generate all the random numbers needed by your app. However, objects are not thread safe. If your app calls methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. If you don't ensure that the object is accessed in a thread-safe way, calls to methods that return random numbers return 0.
The following example uses the C# lock Statement and the Visual Basic SyncLock statement to ensure that a single random number generator is accessed by 11 threads in a thread-safe manner. Each thread generates 2 million random numbers, counts the number of random numbers generated and calculates their sum, and then updates the totals for all threads when it finishes executing.
The example ensures thread-safety in the following ways:
The ThreadStaticAttribute attribute is used to define thread-local variables that track the total number of random numbers generated and their sum for each thread.
A lock (the lock statement in C# and the SyncLock statement in Visual Basic) protects access to the variables for the total count and sum of all random numbers generated on all threads.
A semaphore (the CountdownEvent object) is used to ensure that the main thread blocks until all other threads complete execution.
The example checks whether the random number generator has become corrupted by determining whether two consecutive calls to random number generation methods return 0. If corruption is detected, the example uses the CancellationTokenSource object to signal that all threads should be canceled.
Before generating each random number, each thread checks the state of the CancellationToken object. If cancellation is requested, the example calls the CancellationToken.ThrowIfCancellationRequested method to cancel the thread.
It differs from the first example in the following ways:
The variables to keep track of the number of random numbers generated and their sum in each task are local to the task, so there is no need to use the ThreadStaticAttribute attribute.
The exception that results from task cancellation is surfaced in the Task.WaitAll method. In the previous example, it is handled by each thread.
The random number generator provides methods that let you generate the following kinds of random numbers:
A series of Byte values. You determine the number of byte values by passing an array initialized to the number of elements you want the method to return to the NextBytes method. The following example generates 20 bytes.
A single integer. You can choose whether you want an integer from 0 to a maximum value (Int32.MaxValue – 1) by calling the Next() method, an integer between 0 and a specific value by calling the Next(Int32) method, or an integer within a range of values by calling the Next(Int32, Int32) method. In the parameterized overloads, the specified maximum value is exclusive; that is, the actual maximum number generated is one less than the specified value.
The following example calls the Next(Int32, Int32) method to generate 10 random numbers between -10 and 10. Note that the second argument to the method specifies the exclusive upper bound of the range of random values returned by the method. In other words, the largest integer that the method can return is one less than this value.
A single floating-point value from 0.0 to less than 1.0 by calling the NextDouble method. The exclusive upper bound of the random number returned by the method is 1, so its actual upper bound is 0.99999999999999978. The following example generates 10 random floating-point numbers.
The Next(Int32, Int32) method allows you to specify the range of the returned random number. However, the maxValue parameter, which specifies the upper range returned number, is an exclusive, not an inclusive, value. This means that the method call Next(0, 100) returns a value between 0 and 99, and not between 0 and 100.
You can also use the random T:System.Boolean values, generating random floating point values with a range other than 0 to 1, generating random 64-bit integers, and randomly retrieving a unique element from an array or collection. For these and other common tasks, see the How do you use System.Random to… section.class for such tasks as generating
You can implement your own random number generator by inheriting from the Sample method, which implements the random number generation algorithm. You should also override the Next(), Next(Int32, Int32), and NextBytes methods to ensure that they call your overridden Sample method. You don't have to override the Next(Int32) and NextDouble methods.class and supplying your random number generation algorithm. To supply your own algorithm, you must override the
For an example that derives from the Sample reference page.class and modifies its default pseudo-random number generator, see the
The following sections discuss and provide sample code for some of the ways you might want to use random numbers in your app.
Sometimes you want to generate the same sequence of random numbers in software test scenarios and in game playing. Testing with the same sequence of random numbers allows you to detect regressions and confirm bug fixes. Using the same sequence of random number in games allows you to replay previous games.
You can generate the same sequence of random numbers by providing the same seed value to the Random(Int32) constructor. The seed value provides a starting value for the pseudo-random number generation algorithm. The following example uses 100100 as an arbitrary seed value to instantiate the object, displays 20 random floating-point values, and persists the seed value. It then restores the seed value, instantiates a new random number generator, and displays the same 20 random floating-point values. Note that the example may produce different sequences of random numbers if run on different versions of the .NET Framework.
Providing different seed values to instances of the Random(Int32) constructor, or implicitly by calling the Random() constructor. Most developers call the parameterless constructor, which uses the system clock. The following example uses this approach to instantiate two instances. Each instance displays a series of 10 random integers.class causes each random number generator to produce a different sequence of values. You can provide a seed value either explicitly by calling the
However, because of its finite resolution, the system clock doesn't detect time differences that are less than approximately 15 milliseconds. Therefore, if your code calls the Random() overload to instantiate two objects in succession, you might inadvertently be providing the objects with identical seed values. To see this in the previous example, comment out the Thread.Sleep method call, and compile and run the example again.
To prevent this from happening, we recommend that you instantiate a single The Random class and thread safety earlier in this topic. Alternately, you can use a delay mechanism, such as the Sleep method used in the previous example, to ensure that the instantiations occur more than 15 millisecond apart.object rather than multiple ones. However, since isn't thread safe, you must use some synchronization device if you access a instance from multiple threads; for more information, see
You can retrieve integers in a specified range by calling the Next(Int32, Int32) method, which lets you specify both the lower and the upper bound of the numbers you'd like the random number generator to return. The upper bound is an exclusive, not an inclusive, value. That is, it isn't included in the range of values returned by the method. The following example uses this method to generate random integers between -10 and 10. Note that it specifies 11, which is one greater than the desired value, as the value of the maxValue argument in the method call.
You can call the Next(Int32, Int32) method to retrieve numbers with a specified number of digits. For example, to retrieve numbers with four digits (that is, numbers that range from 1000 to 9999), you call the Next(Int32, Int32) method with a minValue value of 1000 and a maxValue value of 10000, as the following example shows.
The NextDouble method returns random floating-point values that range from 0 to less than 1. However, you'll often want to generate random values in some other range.
If the interval between the minimum and maximum desired values is 1, you can add the difference between the desired starting interval and 0 to the number returned by the NextDouble method. The following example does this to generate 10 random numbers between -1 and 0.
To generate random floating-point numbers whose lower bound is 0 but upper bound is greater than 1 (or, in the case of negative numbers, whose lower bound is less than -1 and upper bound is 0), multiply the random number by the non-zero bound. The following example does this to generate 20 million random floating-point numbers that range from 0 to Int64.MaxValue. In also displays the distribution of the random values generated by the method.
To generate random floating-point numbers between two arbitrary values, like the Next(Int32, Int32) method does for integers, use the following formula:
Random.NextDouble() * (maxValue – minValue) + minValue
The following example generates 1 million random numbers that range from 10.0 to 11.0, and displays their distribution.
The Boolean values. However, you can define your own class or method to do that. The following example defines a class, BooleanGenerator, with a single method, NextBoolean. The BooleanGenerator class stores a object as a private variable. The NextBoolean method calls the Random.Next(Int32, Int32) method and passes the result to the Convert.ToBoolean(Int32) method. Note that 2 is used as the argument to specify the upper bound of the random number. Since this is an exclusive value, the method call returns either 0 or 1.class doesn't provide methods that generate
Instead of creating a separate class to generate random Boolean values, the example could simply have defined a single method. In that case, however, the object should have been defined as a class-level variable to avoid instantiating a new instance in each method call. In Visual Basic, the Random instance can be defined as a Static variable in the NextBoolean method. The following example provides an implementation.
The overloads of the Next method return 32-bit integers. However, in some cases, you might want to work with 64-bit integers. You can do this as follows:
Call the NextDouble method to retrieve a double-precision floating point value.
Multiply that value by Int64.MaxValue.
The following example uses this technique to generate 20 million random long integers and categorizes them in 10 equal groups. It then evaluates the distribution of the random numbers by counting the number in each group from 0 to Int64.MaxValue. As the output from the example shows, the numbers are distributed more or less equally through the range of a long integer.
An alternative technique that uses bit manipulation does not generate truly random numbers. This technique calls Next() to generate two integers, left-shifts one by 32 bits, and ORs them together. This technique has two limitations:
Because bit 31 is the sign bit, the value in bit 31 of the resulting long integer is always 0. This can be addressed by generating a random 0 or 1, left-shifting it 31 bits, and ORing it with the original random long integer.
More seriously, because the probability that the value returned by Next() will be 0, there will be few if any random numbers in the range 0x0-0x00000000FFFFFFFF.
The overloads of the Next method allow you to specify the range of random numbers, but the NextBytes method does not. The following example implements a NextBytes method that lets you specify the range of the returned bytes. It defines a Random2 class that derives from and overloads its NextBytes method.
The NextBytes(Byte, Byte, Byte) method wraps a call to the Next(Int32, Int32) method and specifies the minimum value and one greater than the maximum value (in this case, 0 and 101) that we want returned in the byte array. Because we are sure that the integer values returned by the Next method are within the range of the Byte data type, we can safely cast them (in C#) or convert them (in Visual Basic) from integers to bytes.
Random numbers often serve as indexes to retrieve values from arrays or collections. To retrieve a random index value, you can call the Next(Int32, Int32) method, and use the lower bound of the array as the value of its minValue argument and one greater than the upper bound of the array as the value of its maxValue argument. For a zero-based array, this is equivalent to its Length property, or one greater than the value returned by the Array.GetUpperBound method. The following example randomly retrieves the name of a city in the United States from an array of cities.
A random number generator can always return duplicate values. As the range of numbers becomes smaller or the number of values generated becomes larger, the probability of duplicates grows. If random values must be unique, more numbers are generated to compensate for duplicates, resulting in increasingly poor performance.
There are a number of techniques to handle this scenario. One common solution is to create an array or collection that contains the values to be retrieved, and a parallel array that contains random floating-point numbers. The second array is populated with random numbers at the time the first array is created, and the Array.Sort(Array, Array) method is used to sort the first array by using the values in the parallel array.
For example, if you're developing a Solitaire game, you want to ensure that each card is used only once. Instead of generating random numbers to retrieve a card and tracking whether that card has already been dealt, you can create a parallel array of random numbers that can be used to sort the deck. Once the deck is sorted, your app can maintain a pointer to indicate the index of the next card on the deck.
The following example illustrates this approach. It defines a Card class that represents a playing card and a Dealer class that deals a deck of shuffled cards. The Dealer class constructor populates two arrays: a deck array that has class scope and that represents all the cards in the deck; and a local order array that has the same number of elements as the deck array and is populated with randomly generated Double values. The Array.Sort(Array, Array) method is then called to sort the deck array based on the values in the order array.
Notes to Callers:
The implementation of the random number generator in theclass isn't guaranteed to remain the same across major versions of the .NET Framework. As a result, you shouldn't assume that the same seed will result in the same pseudo-random sequence in different versions of the .NET Framework.
Notes to Inheritors:
In the .NET Framework 1.0 and 1.1, a minimum implementation of a class derived from Sample method to define a new or modified algorithm for generating random numbers. The derived class could then rely on the base class implementation of the Random.Next(), Random.Next(Int32), Random.Next(Int32, Int32), NextBytes, and NextDouble methods to call the derived class implementation of the Sample method.required overriding the
In the .NET Framework 2.0 and later, the behavior of the Random.Next(), Random.Next(Int32, Int32), and NextBytes methods have changed so that these methods do not necessarily call the derived class implementation of the Sample method. As a result, classes derived from that target the .NET Framework 2.0 and later should also override these three methods.
Available since 8
Available since 1.1
Portable Class Library
Supported in: portable .NET platforms
Available since 2.0
Windows Phone Silverlight
Available since 7.0
Available since 8.1
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.