Generating random-numbers in C#

By Jun 02, 2018

Description:

Here we explain how to generate random numbers in C# and give some examples of using a random number generator.

Preferencesoft

We will see how to generate random integers, random integers between two bounds, an array of random bytes, random double numbers. We will give some examples of use.

Random number generation is often useful in games, cryptography, simulations, software testing.

In C#, the Random class is used to generate random numbers. These are in fact pseudo-random numbers obtained from a recurring sequence whose first term called seed can be initialized from the clock.

Generating random integers

To generate a random integer greater than or equal to 0 and less than an integer n, an instance of the Random class is created and the Next method  with the n parameter is called to receive it.

using System;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            int r = rnd.Next(18);
            Console.WriteLine("Random integer: " + r);
        }
    }
}

Output

Random integer: 12

An overload of the Next method has two integer parameters a, b, and is used to generate a random integer greater than or equal to a and less than b.

using System;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            int r = rnd.Next(1,6);
            Console.WriteLine("Random integer: " + r);
            int r1 = rnd.Next(int.MaxValue-8,int.MaxValue);
            Console.WriteLine("Random integer: " + r1);
        }
    }
}

Output

Random integer: 4
Random integer: 2147483642

Let's implement a simple game in which the computer will generate a random secret number that a player will have to guess in at most 5 tries.

The computer will give in case of failure, a random number close enough to the secret number (at a distance not more than 5)

using System;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            int secret = rnd.Next(1,100);
            Console.WriteLine("I think of a number between 1 and 100.");
            Console.WriteLine("Try to guess this number.");
            Console.WriteLine("You have 5 tests and to help you, I will give you after each test, random numbers close to this number");
            Console.WriteLine("(at a distance of not more than 5).");
            bool found = false;
            int count = 0;
            Random r = new Random();
            while (!found && count <= 5) 
            {
                Console.WriteLine("Give me a number");
                int ans = int.Parse(Console.ReadLine());
                count++;
                if (ans == secret) found = true;
                else 
                {
                    Console.WriteLine("No, no luck");
                    int approx = rnd.Next(Math.Max(1,secret-5),Math.Min(100,secret+5));
                    Console.WriteLine("The number sought is close to "+approx);
                }

            }
            if (found) Console.WriteLine("You have won in "+count+" tries");
            else 
            {
                Console.WriteLine("You lost :(");
                Console.WriteLine("The secret number was: "+secret);
            }
        }
    }
}

Generating random byte arrays

Here is an example that generates an array of 20 bytes randomly:

using System;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            byte[] ba = new byte[20];
            rnd.NextBytes(ba);
            Console.WriteLine("Random bytes: ");
            for (int i=0; i<20; i++)
                Console.Write(ba[i]  + "  ");
        }
    }
}

Output

Random bytes:
152 232 37 160 170 239 110 196 76 194 87 198 139 43 203 225 222 22 97 120

Generating random double numbers

To generate a real number of type double of the interval [0, 1), an instance of the Random class is created and the NextDouble method is called returning a decimal number having 15 digits after the comma.

using System;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            double r = rnd.NextDouble();
            Console.WriteLine("Random double: " + r);
        }
    }
}

Output

Random double: 0,788102438109043

To generate a random double between a and b (ab), we often proceed as follows:

using System;

namespace Example
{
    class Program
    {
        public class RandomDouble
        {
            double a_ = 0, b_ = 1;
            Random rnd;
            public RandomDouble(double a, double b)
            {
                 rnd = new Random();
                 a_ = a;
                 b_ = b;
            }
            public double Next()
            {
                return a_ + (b_ - a_) * rnd.NextDouble();
            }
        }

        static void Main(string[] args)
        {
            RandomDouble rd = new RandomDouble(12,150);
            Console.Write(rd.Next());
        }
    }
}

But this method does not give satisfactory results when b-a is large.

In fact, by multiplying by b-a, we lose precision. For example if the actual number generated is equal to 0.0123456789 and b-a = 1000000000 then we obtain the number 12345678.9.

Here is another method of rounding the b-a difference to the next larger integer n, to generate a random integer between 0 and n-1 to which a random real number of the interval is added [0, 1). That gives a real number of the interval [0, n) which is brought back to the interval [0, b-a) then [a, b).

using System;

namespace Example
{
    class Program
    {
        public class RandomDouble
        {
            double a_ = 0, b_ = 1;
            Random rnd;
            public RandomDouble(double a, double b)
            {
                 rnd = new Random();
                 a_ = a;
                 b_ = b;
            }
            public double Next()
            {
                return a_ + (b_ - a_)*rnd.NextDouble();
            }
            public double FineNext()
            {
                int n=(int)Math.Ceiling(b_-a_);
                double c=(b_-a_)/n;
                return a_ + (rnd.Next(n) + rnd.NextDouble()) * c;
            }
        }


  static int filter(double x)
  {
    if (x>0 && x<0.2) return 1;
    else if (x>11 && x<11.2) return 2;
    else if (x>40 && x<40.2) return 3;
    else if (x>60 && x<60.2) return 4;
    else if (x>100 && x<100.2) return 5;
    else if (x>120 && x<120.2) return 6;
    return 0;
  }
        static void Main(string[] args)
        {
            Random rnd = new Random();
            RandomDouble rd = new RandomDouble(0,1500000000);
            int[] ball1 = new int[7]{0,0,0,0,0,0,0};
            int[] ball2 = new int[7]{0,0,0,0,0,0,0};
            for (long i=0; i<20000000000;i++)
            {
                double r = rd.FineNext();
                int bb=filter(r);
                ball1[bb]++;
                r = rd.Next();
                bb=filter(r);
                ball2[bb]++;
            }
            double s=0.0;
            for (int i=1; i<7;i++)
            {
                s += ball1[i];
                Console.Write(ball1[i]+"  ");
            }
            Console.WriteLine();
            for (int i=1; i<7;i++)
                Console.Write(ball1[i]/s + "  ");
            Console.WriteLine();Console.WriteLine();
            s=0.0;
            for (int i=1; i<7;i++)
            {
                s += ball2[i];
                Console.Write(ball2[i] + "  ");
            }
            Console.WriteLine();
            for (int i=1; i<7;i++)
                Console.Write(ball2[i]/s + "  ");
        }
    }
}

Output

4 3 0 3 1 3
0.285714285714286   0.214285714285714   0   0.214285714285714   0.0714285714285714   0.214285714285714

0 6 0 4 0 9
0   0.315789473684211   0   0.210526315789474   0   0.473684210526316

CSharp

Categories

Share

Follow


KodFor Privacy Policy