Why Does It Appear That My Random Number Generator Isn't Random in C#

Why does it appear that my random number generator isn't random in C#?

The problem with min = 0 and max = 1 is that min is inclusive and max is exclusive. So the only possible value for that combination is 0.

Why does this Random Number Generator not random?

new Random() uses the current time as the seed value. Thus, if you are calling this function multiple times in a very short time span, it might return the same value. Here's the explanation from MSDN:

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers.

C# Random Numbers aren't being random

My guess is that randomNumber creates a new instance of Random each time... which in turn creates a new pseudo-random number generator based on the current time... which doesn't change as often as you might think.

Don't do that. Use the same instance of Random repeatedly... but don't "fix" it by creating a static Random variable. That won't work well either in the long term, as Random isn't thread-safe. It will all look fine in testing, then you'll mysteriously get all zeroes back after you happen to get unlucky with concurrency :(

Fortunately it's not too hard to get something working using thread-locals, particularly if you're on .NET 4. You end up with a new instance of Random per thread.

I've written an article on this very topic which you may find useful, including this code:

using System;
using System.Threading;

public static class RandomProvider
{
private static int seed = Environment.TickCount;

private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>
(() => new Random(Interlocked.Increment(ref seed)));

public static Random GetThreadRandom()
{
return randomWrapper.Value;
}
}

If you change your new Random() call to RandomProvider.GetThreadRandom() that will probably do everything you need (again, assuming .NET 4). That doesn't address testability, but one step at a time...

Random numbers don't seem very random

This is similar to the Birthday Problem. Given a group of n people, What is the probability that two share the same birthday1? It's higher than you'd think.

In your case, what are the odds that randomly picking a number between 0 and 1,073,741,823 n times will give you a duplicate?

One approximation from the link above is 1-exp(-(n*n)/(2*d)). If n=40,000 that equates to about a 52.5% probability that a duplicate is chosen, so seeing duplicates after 40,000 picks on average seems reasonable.


1assuming that birthdays are uniformly distributed universally, which is not the case in reality but is "close enough" and makes the math easier

C# Random Number Not Random Enough

To everyone who said the problem was someplace else, not in my random number routine, that there must have been a bug in some of my other code,,, you were right.

I discovered that by storing/retrieving my location in/from the Location of a rectangle, I had been truncating its components down to ints.

In retrospect, it should have been a clue that by playing with the scaleFactor, by adding then removing a same-range random number, already realized to have been increasing the range of the number, I got my so-close-to-working solution to have numbers that actually were different enough when truncated to cover more of the range.

Not exactly sure who to credit with the answer for this.

My final routine code turned out to be:

public static double TwoPi = Math.PI * 2f;
public static Vector2 rndV2gtHalf(float scaleFactor)
{
double dir = random.NextDouble() * TwoPi;
return new Vector2(
(float)Math.Cos(dir) * scaleFactor,
(float)Math.Sin(dir) * scaleFactor
);
}

and here is the visual result:
Sample Image

Random.Next is not giving a random number

I would suggest seeding the random numer generator too. As I understand, you will end up with the same psuedo-random number sequence every time you run the application. I may be mistaken.

int Seed = (int)DateTime.Now.Ticks;
Random randomListCell = new Random(Seed);

Why initializing new System.Random DOESN'T produce the same output?

That code was never guaranteed to produce the same numbers, although it typically would as the seed was initialized from the current system time, and this has been the cause of many Stack Overflow questions.

The documentation for the parameterless constructor states (emphasis mine):

The default seed value is derived from the system clock, which has finite resolution. As a result, on the .NET Framework only, different Random objects that are created in close succession by a call to the parameterless constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. [... ] Note that this limitation does not apply to .NET Core.

So it looks like this was basically fixed in Core. But it wasn't always fixed in Core. I've just created a test project targeting multiple frameworks, adding a bit of warmup code to avoid JIT delays changing the seed for the next iteration, and it looks like .NET Core 1.x had the same issue as the desktop framework. It was fixed for 2.0, I suspect.

C# Random isn't producing a random result

You need to put the random number generation in the loop :

while (response == "YES") {
int compChoice = random.Next(1, 4);

Otherwise, it will generate the number once and take that one all the time

See random.Next as "Random, can I get the next random number", as you did it with the Console.ReadLine() for the second player

Is the C# random number generator guaranteed to be stable?

No, the result from the same seed can vary across versions of the framework, and it's in the documentation here:

The implementation of the random number generator in the Random class 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.

That documentation also contains variations of this advice in other sections, e.g. in Retrieve the same sequence of random values:

The following example uses 100100 as an arbitrary seed value to instantiate the Random 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.

And:

However, note that Random 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.



Related Topics



Leave a reply



Submit