C# Random Number Examples

Get random numbers with the Random class. Random has a Next method and can be used as a field.
Random. Ants march in the shade of an oak tree. They avoid obstacles as they collect food. They work together. Order is in everything the ant does.
An external event (like a tree branch falling) then occurs. This random event disrupts order. For this simulation, a random number generator could be used.
Random class. Let us simulate a random event. Random, a class, is available when we include (or reference) the System namespace. We use Random and Next() with 2 arguments.

Argument 1: The first argument to Next() is the inclusive minimum number allowed by the random number generator.

Argument 2: This argument is an exclusive maximum. So it never occurs in the output—all numbers must be lower.

C# program that uses Random using System; class Program { static void Main() { // ... Create new Random object. Random random = new Random(); // ... Get 3 random numbers. // These are always 5, 6, 7, 8 or 9. Console.WriteLine("RANDOM: " + random.Next(5, 10)); Console.WriteLine("RANDOM: " + random.Next(5, 10)); Console.WriteLine("RANDOM: " + random.Next(5, 10)); } } Output RANDOM: 6 RANDOM: 5 RANDOM: 9
Static. A static thing only has one instance. A static Random improves programs. Here the Random object is stored as a static variable. Methods that use it will still get good random ints.

Tip: If you used a new Random at the method level as a local, it would not be as good. The time-dependent seed would repeat itself.

C# program that uses static Random using System; class Program { static void Main() { // Call a method that uses class-level Random. UseStatic(); // Call the same method. // ... The random number sequence will still be random. UseStatic(); } static Random _random = new Random(); static void UseStatic() { // Use class-level Random. // ... When this method is called many times, it still has good Randoms. int result = _random.Next(); // If this method declared a local Random, it would repeat itself. Console.WriteLine("STATIC RANDOM: " + result); } } Output STATIC RANDOM: 810380956 STATIC RANDOM: 123622001
Repeated randoms. This is a bad example of code—do not use it in a real program. When we create a Random object, its seed is based on the time.

So: If we create many Random objects at the same time (or close in time) our random numbers will repeat.

Tip: Use a field or pass a Random as an argument to avoid repeated random numbers.

C# program that causes repeated random numbers class Program { static void Main() { Test(); Test(); Test(); } static void Test() { // Create random and use it. // ... This is time-dependent, so can repeat if called many times. var random = new System.Random(); System.Console.WriteLine("CURRENT: " + random.Next()); } } Output CURRENT: 747025912 CURRENT: 747025912 CURRENT: 747025912
Exception, minValue. When calling Next(), be careful that the "minimum value" is lower than the "maximum value." So the first argument is always lower than the second.
C# program that shows Random exception using System; class Program { static void Main() { var random = new Random(); // First argument must be lower than the second. int result = random.Next(20, 10); } } Output Unhandled Exception: System.ArgumentOutOfRangeException: 'minValue' cannot be greater than maxValue. Parameter name: minValue at System.Random.Next(Int32 minValue, Int32 maxValue) at Program.Main()...
Max. Here is another example of the maxValue parameter on the Next method. When you pass an integer to Random.Next(), you get a result in the range of 0 to maxValue - 1.

Important: You will not get the actual parameter argument you passed, as the top is exclusive.

Also: Another option is to pass the Next() method two parameters. The lower bound is inclusive, but the upper one isn't.

C# program that uses Random with parameter using System; class Program { static void Main() { F(); F(); F(); F(); F(); F(); } static Random _r = new Random(); static void F() { int n = _r.Next(5); // Can return 0, 1, 2, 3, or 4. Console.WriteLine(n); } } Output 2 1 1 0 3 2
Modulo division. We can use modulo division on random numbers. Here we get 10 random numbers, then use modulo to get an index into a small array. Then we increment random elements.Modulo

Note: Using arguments to Next() that are in the correct range would be better than using modulo, as the code is more direct and simpler.

However: If we wish to use a single random number in multiple ways, modulo division can help here.

Tip: If the array length is 3, and we have a random number and use modulo division by 3, we get the values 0, 1 and 2.

C# program that uses modulo with Random using System; class Program { static void Main() { int[] array = new int[3]; var random = new Random(); // Get 10 random numbers, then use modulo to increment array elements. for (int i = 0; i < 10; i++) { int result = random.Next(0, 100); int modulo = result % array.Length; array[modulo]++; } // Display the end result. for (int i = 0; i < array.Length; i++) { Console.WriteLine("ARRAY {0} = {1}", i, array[i]); } } } Output ARRAY 0 = 2 ARRAY 1 = 4 ARRAY 2 = 4
Randomize string. This example is a bit more complex. It randomizes the chars in a string. It sorts on a random number to shuffle data.

OrderBy: The program uses the LINQ method syntax, which combines the OrderBy with a lambda expression.

OrderBy

Result: ToArray converts the enumerable letters in the statement to a string again, producing the final result: a randomized string.

ToArrayString Constructor
C# program that randomizes strings using System; using System.Linq; class Program { static void Main() { // The source string. const string original = "senators"; // The random number sequence. Random num = new Random(); // Create new string from the reordered char array. string rand = new string(original.ToCharArray(). OrderBy(s => (num.Next(2) % 2) == 0).ToArray()); // Write results. Console.WriteLine("original: {0}\r\nrand: {1}", original, rand); Console.Read(); } } Output original: senators rand: tossenar
Bytes. You can also call the NextBytes method on the Random type to acquire a random byte array. Each byte has the decimal range of 0 to 255.

Info: The NextBytes method allows you to get a random value of arbitrary length in one method invocation.

Tip: While an integer is only 4 bytes, you can use NextBytes to get much more random data at once.

C# program that uses NextBytes method using System; class Program { static void Main() { // Put random bytes into this array. byte[] array = new byte[8]; // Use Random class and NextBytes method. // ... Display the bytes with the following method. Random random = new Random(); random.NextBytes(array); Display(array); random.NextBytes(array); Display(array); } static void Display(byte[] array) { // Loop through and display bytes in the array. foreach (byte value in array) { Console.Write(value); Console.Write(' '); } Console.WriteLine(); } } Output 177 209 137 61 204 127 103 88 167 246 80 251 252 204 35 239
Random optimization, cache. Suppose we want many random ints, but having high-quality random numbers is not important. We can pre-populate a List with random ints.

And: With a modulo expression, we can index those ints and use them in place of a call to Random.Next.

Here: We compare a call to Random.Next with a List element access. It is faster to get precomputed random ints.

Tip: You could also store a static int array of previously-generated random ints, and just access that, for faster startup time.

C# program that uses cache for Random ints using System; using System.Collections.Generic; using System.Diagnostics; class Program { static Random _random = new Random(); static List<int> _randomCache = new List<int>(); static void AddRandoms() { // Add random numbers to a list for later use. for (int i = 0; i < 1000; i++) { _randomCache.Add(_random.Next()); } } const int _max = 10000000; static void Main() { // Precompute some random ints. AddRandoms(); // Version 1: get new random int. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int random = _random.Next(); if (random < 0) { return; } } s1.Stop(); // Version 2: use cached random int from list. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int random = _randomCache[i % _randomCache.Count]; if (random < 0) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } } Output 8.93 ns Random.Next() 2.79 ns Random Cache (List)
Some notes. With the Random class, we generate pseudo-random numbers. A typical "random" number generator cannot return a truly random number.

Instead: A random number generator returns sufficiently random (random-appearing) numbers.

Int, uint
Review. Here we consider the Microsoft resource about the Random class. It indicates that (by default) the Random object uses a seed value.

Important: This means that if the time is the same when 2 Randoms are created, you have a problem.

Quote: The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to improve randomness is to make the seed value time-dependent.

Random Class: Microsoft Docs
Review, continued. Microsoft further states how we can use Random for the best performance in our C# programs. Some advice is provided.

One random: We should "create one Random to generate many random numbers over time." This can be done with a local variable or field.

Fields. Suppose a method uses a local Random and creates it on each call. If it is called twice in the same time frame, its random numbers may repeat.

State: In object-oriented programming, we think of classes as machines that must store state.

And: The Random() object has state, which is dependent on time. It is not stateless.

Thus: It is not ideal to create multiple Randoms when you can use only one. With one, we improve randomness and performance.

RNGCryptoServiceProvider. The Random class is not as random as possible. Do not use it for cryptography. For cryptography in the .NET Framework, use the RNGCryptoServiceProvider class.RNGCryptoServiceProvider

Note: The RNG stands for random number generator. The name is confusing because of its abbreviation.

Shuffle array. A deck of cards is shuffled. In shuffling an array, we rearrange elements in a random order. I use a tested algorithm.ShuffleShuffle: Fisher-Yates
Random examples. There are more examples of random number usage and other random data generation tactics on this site. For a random string, try using GetRandomFileName.Random Path: GetRandomFileNameRandom Lowercase LetterRandom ParagraphsRandom String
A summary. Be careful of creating new Randoms—the results may start to repeat. Instead, reusing the same Random is a more ideal approach to pseudo-random number generation in C#.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
HomeSearch
Home
Dot Net Perls