how good is .NET's Random for making random numbers?

  • Thread starter Thread starter Zytan
  • Start date Start date
As mentioned earlier, the most common reason for bad randomness is
creating several Random objects. If used correctly, the randomness is
pretty good.

Yup, I am not doing this, so that's not the issue for me.
If you create a very large number of random numbers, you will be able to
see some subtle patterns. If you for example pick colors by random for
every pixel in a large image, your brain will probably be able to
distinguish some patterns, as the random numbers are not completely random.

Has anyone tried this? I'd like to see the result. I'll do it myself
if no one has.
If you need really really really good randomness, there is a random
generator in the System.Security.Cryptography namespace. It's used to
create encryption keys, where the demands for randomness is extremely high.

Ok, thanks.

Zytan
 
Here are some random numbers:
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5.

No, you copied and pasted. They are completely not random! ;) But,
I get your point.

My real question is: Is C#'s Random() better than C's rand()?
(because C's rand() showed patterns.)

Zytan
 
The problem with randomness is that you never can tell.

I'm feeling warm and fuzzy when I say, statistically fuzzy is how we should
all feel.

Jon
 
You can always look at the Random class in Reflector to see exactly
what it does. It's plain .NET managed code.

It's more than 3 lines, but not all that much more. :-)

Sam

------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.
 
Zytan said:
I am 99.9% sure you are right, and i think the same thing, but I still
just want to know if it's better than the 3 lines of code C's rand()
was made from, since with extremely little effort,

Typical C RTL rand() has poor randomness in low digits. You always had
to use division rather than modulus to get good results.
you could see
patterns. Not like the above, but when shown in a visual way, where
you can 'see' the numbers' meanings (not their digits), you could see
the same stuff occured over and over again. Especially if you made
sure to sequence them in groups of even binary numbers ;)

It sounds like you may have been using modulus, which would have left
the least significant digits untouched, especially if your modulus was
even and you were grouping resulting numbers by even/odd.

-- Barry
 
Zytan said:
It seems that the similar numbers pop up twice in a row sometimes, far
too often.

How often, with what range? Can you tell us more about what you're
doing?
 
Jon Davis said:
It's really, REALLY freaking annoying when Microsoft writes, publishes, and
announces an elaborate article like this, but does not fix the one line of
documentation that contradicts it FIRST. :(

http://msdn2.microsoft.com/en-us/library/c5kehkcz(vs.71).aspx

Eek, that's terrible - not just for the typeof(...) bit, but also for
recommending locking on "this" which is also a no-no :(

I've done the whole "rate and give feedback" bit. Not sure whether
it'll help though.
 
Has anyone tried this? I'd like to see the result. I'll do it myself
if no one has.

Seemed like an interesting thing to try. Here you go:
http://www.petrotta.org/random.png
I can't spot any patterns in it, not that I expected to. It's
interesting to note that compressing to png saved only 18 bytes out of
the 459K bitmap. That's a sign of random data :-)

Here's the source. It's a pretty naive (and slow) creation of an
image with random grayscale data. I'm sure there are better ways to
do this. I'd like to try creating 16bpp images too.

using System;
using System.Drawing;

namespace RandomGrays
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 3)
{
throw new ArgumentOutOfRangeException("Usage: randomgrays <width>
<height> <outfile>");
}

int width = Convert.ToInt32(args[0]);
int height = Convert.ToInt32(args[1]);
string fileName = args[2].ToString();
Bitmap b = new Bitmap(width, height);
Random r = new Random();
for (int x = 0; x < width; x++)
{
for (int y = height - 1; y >= 0; y--) // eye scan order == write
order
{
int random = r.Next(255);
b.SetPixel(x, y, Color.FromArgb(random, random, random));
}
}
b.Save(fileName);
}
}
}

Michael
 
Has anyone tried this? I'd like to see the result. I'll do it myself
if no one has.

(apologies if this is a repost. I don't believe my first attempt went
out)

Seemed like an interesting thing to try. Here you go:
http://www.petrotta.org/random.png

A 640x480 bitmap of random grayscale pixels. Looks pretty random to
me, if a little bipolar. A histogram shows that it's pretty flat
across the values, though.

Here's the source. I'm sure there are better ways to do this, if only
because this was dead slow:

using System;
using System.Drawing;

namespace RandomGrays
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 3)
{
throw new ArgumentOutOfRangeException("Usage: randomgrays <width>
<height> <outfile>");
}

int width = Convert.ToInt32(args[0]);
int height = Convert.ToInt32(args[1]);
string fileName = args[2].ToString();
Bitmap b = new Bitmap(width, height);
Random r = new Random();
for (int x = 0; x < width; x++)
{
for (int y = height - 1; y >= 0; y--) // eye scan order == write
order
{
int random = r.Next(255);
b.SetPixel(x, y, Color.FromArgb(random, random, random));
}
}
b.Save(fileName);
}
}
}

Michael
 
Anyone do any tests on it? I would assume it has improved since C's
rand(), but who knows. For some reason, and it could just be
coincidence, I seem to see patterns. But even a crappy rand()
function should be good enough to avoid that, so i may be seeing
things.

Zytan
Have you googled for the Diehard tests?

rossum
 
Zytan said:
Anyone do any tests on it? I would assume it has improved since C's
rand(), but who knows. For some reason, and it could just be
coincidence, I seem to see patterns. But even a crappy rand()
function should be good enough to avoid that, so i may be seeing
things.

It's likely that .NET's Random is almost exactly as good as the C rand()
function - AFIAK, they're both simple linear congruential generators.
They're fast, but not particularly random.

Without getting into crypto generators (which are horrifically slow,
compared to an LCG), there are a number of RNG algorithms that can do a lot
better than a simple LCG. Consult your favorite algorithms book (Sedgewick,
Knuth, Rivest, etc) for details.

-cd
 
Samuel said:
In this particular example you already have a static variable
appropriate for locking anyways so no need to create a new
synchronization object, just lock AppRandom.

There is no need to create a synchronisation object, but you might want
to. :)

It's good to have a private object that is only used for the
synchronisation, that way there is no other code that can lock on the
same object (causing a deadlock), and as the object isn't used for
anything else you won't ever have any reason to make it public.
 
Zytan said:
Anyone do any tests on it? I would assume it has improved since C's
rand(), but who knows. For some reason, and it could just be
coincidence, I seem to see patterns. But even a crappy rand()
function should be good enough to avoid that, so i may be seeing
things.

..NET Random uses "Donald E. Knuth's subtractive random number
generator algorithm" says the docs.

Decompile code indicates that it uses an array of size 56.

It seems to be a special case of modern MRG with coefficients of 1.

Based on that:
- Knuth is who he is
- MRG's are generally considered good
- MS choose that algorithm
then I am sure that it is better than the standard C rand()
based on simple LCG's.

So check if there is a problem and if yes then check your code.

You can do simple tests by tabulating high bits and low bits
in 1D, 2D etc..

Arne
 
Alberto said:
If the Random class is not good enough for you, you may wish to take
a look at the System.Security.Cryptography.RNGCryptoServiceProvider,
which provides a cryptographically-robust random number generator.

Note that this class is not necessarily more random than the
normal Random.

It is just more secure in the sense that it is less predictable.

Arne
 
* Alun Harford wrote, On 16-5-2007 16:15:
Here are some random numbers:

5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5.

The problem with randomness is that you never can tell.

Alun Harford

That reminds me of the following Comic on XKCD:

http://imgs.xkcd.com/comics/random_number.png

Fesse
 
It seems that the similar numbers pop up twice in a row sometimes, far
How often, with what range? Can you tell us more about what you're
doing?

No, not without analysis that would take too much time. I'm sure even
with C's crappy rand() function that it can be shown that it is pretty
random, and such repetitions are normal, as they are with real random
numbers.

My only concern was whether .NET's Random() is better than C's
rand()...? I could see patterns in C's rand() fairly easy, without
even looking specifically for them.

Zytan
 
Typical C RTL rand() has poor randomness in low digits. You always had
to use division rather than modulus to get good results.

Good point. Very true.
It sounds like you may have been using modulus, which would have left
the least significant digits untouched, especially if your modulus was
even and you were grouping resulting numbers by even/odd.

I'm not sure what the numbers were, I really didn't have enough
numbers to make a prope stab at whether or not it was random. Just
the concern that it may not be, caused me to start this thread.

Thanks, Barry

Zytan
 
Seemed like an interesting thing to try. Here you go:http://www.petrotta.org/random.png

Thanks.
A 640x480 bitmap of random grayscale pixels. Looks pretty random to
me, if a little bipolar. A histogram shows that it's pretty flat
across the values, though.

I tried it with 256 and 512 widths, which really show the flaws in C's
rand(), but Random() seems to hold up well.
Here's the source. I'm sure there are better ways to do this, if only
because this was dead slow:

I used int random = r.Next(256); to give 0..255 values (256 is
maximum, but it returns one less than max)

And, eye scan order starts at 0, not at the bottom. Bitmaps are
stored in the file bottom up, but are still displayed with row 0 at
the top.

I think we can conclude Random() is better than C's rand().

Thanks, Michael

Zytan
 
Back
Top