Craig Johnston
Craig Johnston

Reputation: 807

C#: random number issue

See the following:

   for (int i=0; i<2; i++) {
        // do some stuff
        r = new Random((int)DateTime.Now.Ticks);
        iRandom = r.Next(30000);
        // do some other stuff
   }

Don't ask me how, but iRandom is sometimes the same for both iterations of the loop. I need iRandom to be different for each iteration. How do I do this?

Upvotes: 2

Views: 859

Answers (6)

David
David

Reputation: 2910

A REALLY nice explanation: http://msdn.microsoft.com/en-us/library/system.random.aspx

Upvotes: 1

Dean Chalk
Dean Chalk

Reputation: 20451

try creating your Random with a non time-based seed, otherwise the seed may be the same (and the random number same also)

for (int i = 0; i < 2; i++)
{
    // do some stuff
    r = new Random(Guid.NewGuid().GetHashCode());
    iRandom = r.Next(30000);
    // do some other stuff
}

Upvotes: 3

Reb.Cabin
Reb.Cabin

Reputation: 5567

For some surprises with Math.Random doubles versus RNGCryptoServiceProvider, try plotting the results of the following (say, using a spreadsheet). This code will run in LinqPad (www.LinqPad.net). It's worth a look :)

void Main()
{
{
    var ds = Enumerable.Range(1, 30).Select(i => new Random(i).NextDouble());
    ds.Dump();
}
{
    var csp = new System.Security.Cryptography.RNGCryptoServiceProvider();
    var bs = new byte[8 * 30];
    var ds = new double[30];
    csp.GetBytes(bs);

    for (var i = 0; i < 30; i++)
    {
        var d = BitConverter.ToDouble(bs, i * 8);
        while (d == 0D || Double.IsNaN(d))
        {
            var bytes = new byte[8];
            csp.GetBytes(bytes);
            d = BitConverter.ToDouble(bs, 0);
        }
        ds[i] = Math.Log10(Math.Abs(d));
    }

    ds.Dump();
}

}

Upvotes: 2

glowworms
glowworms

Reputation: 410

DateTime.Now.Ticks is a Int64 type. If you cast to an int, it could be casting to the same value for the seed and therefore giving you the same random number.

No need to reseed or recreate the Random object once it is created. Just reuse the object and obtain the next random number.

Upvotes: 0

Reb.Cabin
Reb.Cabin

Reputation: 5567

Try seeding with a new Guid, or, better yet, use the Cryto provider... Here's a Stko article with code

Best way to seed Random() in singleton

Upvotes: 0

Flipster
Flipster

Reputation: 4401

Change your loop to this:

    r = new Random((int)DateTime.Now.Ticks);

   for (int i=0; i<2; i++) {
    // do some stuff
    iRandom = r.Next(30000);
    // do some other stuff
   }

In other words, put the creation of the Random object outside the loop.

Upvotes: 8

Related Questions