Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can rand() really be this bad? [closed]

Tags:

c++

random

macos

lol

Above is an example image generated by using rand() to get random coordinates and add a constant to the pixel value at those coordinates. This is how it looks from a few thousand iterations. I'm using the rand() from stdlib.h in Mac OS X Lion, giving it time(NULL) as the seed.

You can clearly see the vertical lines, as if the ones with an odd x-coordinate have higher values than those with even x-coordinates.

How would I implement a better algorithm, or where can I find one that doesn't have many dependencies? (I would prefer a header-only file).

Here's the code (sorry it took me so long):

void generate(int iterations = 1) {
 for (unsigned int x = 0;x < (area * 4);++x) {
  map[rand() % area] += 1;
 }
 number a = min();
 number b = max();
 for (int i = 0;i < area;++i) {
  map[i] -= a;
  map[i] /= b;
 }
}

Map contains double-floats and is later turned into RGB values.

like image 720
slartibartfast Avatar asked May 21 '12 20:05

slartibartfast


4 Answers

C++11 provides pretty useful random number functionality in random. See here and here for more details.

like image 142
juanchopanza Avatar answered Oct 16 '22 23:10

juanchopanza


Have you tried arc4random()? It provides much stronger and more uniform random values than rand().

You could also try SecRandomCopyBytes(), which is part of Security.framework. This basically just reads from /dev/random.

like image 30
Lily Ballard Avatar answered Oct 17 '22 00:10

Lily Ballard


I think it would be most important to see how you use rand() to extract the coordinates. What is really surprising is, that you only see a pattern in the x coordinates, but not in the y ones. If there really was a deficiency in rand() it should appear in both.

That said, I could attempt a guess where these patterns come from: rand() is well known to produce more randomness in the high bits than in the low ones. Hence one should never use modulo to extract a smaller range, because this way one will only get the low bit parts with less randomness.

From this knowledge I would guess that you were extracting the low bits to produce the x values and the high bits to extract the y values. This would give you a much more random pattern along the y axis than along the x axis.

If this is now what you are doing, there still must be some artifact in your code, which causes larger randomness across the y axis than along the x axis. So without seeing your code it is hard to tell if this implementation is flawed.

like image 35
LiKao Avatar answered Oct 16 '22 22:10

LiKao


On the mac you can just use random instead of rand. The man page for random notes the following:

BUGS

About 2/3 the speed of rand(3).

The historical implementation used to have a very weak seeding; the random sequence did not vary much with the seed. The current implementation employs a better pseudo-random number generator for the initial state calculation.

Applications requiring cryptographic quality randomness should use arc4random(3).

like image 1
Nathan S. Avatar answered Oct 16 '22 22:10

Nathan S.