Skip to main content
GameDev.net gamedev.net
🔒 Locked

Question about the build in Rand() function.

Started by JackBid Apr 27, 2013 at 10:27 PM 4 replies 2.6k views
Original Post
JackBid
JackBid

So I think in just about every programming language there is some sort of build in Rand() function which chooses a random number between 0-1 which can then be multiplied to achieve a random point between two numbers.

My question is; in simple terms, does anyone know how the rand() function works? I was just thinking about it and don't really understand how it is possible to do. Theoretically what is going on inside that function?

P.S. I am a beginner and if anything said above was incorrect please forgive me.

Servant of the Lord
Servant of the Lord
These are called "Pseudorandom number generators". 'pseudo' because they are not actually random, and do repeat, but their patterns are so far apart that it seems random.

If I want a number between 1 and 100, I can start off with '1', and add '6' to each value, my pattern of numbers goes like this:
1 7 13 19 ...snip... 85 91 97
Then the next value, 103, loops back around to '3'. Now it goes:
3 9 15 21 ...snip... 87 93 99
5 11 17 23 ...etc... 77 83 89 95

It generates 50 numbers before the pattern repeats. By 'pattern', it might touch the same value multiple times (it might generate '11' four or five times in the 50 numbers), but the full pattern of the generator doesn't repeat until after 50 numbers are generated.

In my example, the full pattern is:
1     7     13    19    25    31    37    43    49    55
61    67    73    79    85    91    97    3     9     15
21    27    33    39    45    51    57    63    69    75
81    87    93    99    5     11    17    23    29    35
41    47    53    59    65    71    77    83    89    95

Total: 50

If you have a 32 bit number (about 4 billion values) and create a algorithm that visits every number (hopefully an almost equal amount of times, not biased towards specific numbers), and does so in a way where the numbers can jump forward or backward (It might go 1 19 13 7 instead of 1 7 13 19 like my example did), then you'd have a decent pseudorandom generator.

You just need a more complex algorithm than just 'add 6'. Usually, they do this by manipulating the bits of the number, as well normal arithmetic.
Here's an example that provides better results (still not fantastic though), but is simple enough to understand.
There are many of them, some okay, others much better.

Having the results as a float between 0.0 and 1.0 instead of an integer between 0 and is the same idea, just different final representation.
Bacterius
Bacterius

The most common and simplest to implement is probably the LCG (linear congruential generator) which is pretty much just:

next value = (a * old value + b) mod m

For some initial value. With careful selection of the constants a, b, m, the generator will have maximum period equal to m values before repeating (in general, m is 2^32 or 2^64). But it kind of sucks in practice. If you plot the results they don't look random at all but display a lattice structure, even though individual values look random enough.

It is possible to implement true random number generation in computers, but it cannot be done completely in software due to determinism. For instance, under Linux, reading /dev/random will give you truly random bits, which are usually obtained from various unpredictable sources such as keystrokes, mouse movements, disk access latency, thermal noise, and can even use stuff produced by dedicated hardware (for instance, there are relatively cheap hardware random number generators based on quantum physics).

But for almost all applications a pseudorandom number generator will do fine. If you use C++11 you can check out the extra random number generators implemented in the standard library, that way you don't have to rely on rand() and can use any available generator without even having to code it yourself. Otherwise implementations exist in other languages, I am sure.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”
jbadams
jbadams

Note that when using pseudo-random numbers you're almost always able to provide a "seed" in some way; this is usually something you'll want to do once at the start of your program.

By providing a different seed you get a different sequence of random numbers, whilst providing the same one will give you the same sequence each time. This can be useful if you're using your "random" numbers to generate maps, spawn bad guys, etc., because you can re-produce the same results each time by using the same seed values.

- Jason Astle-Adams
iMalc
iMalc
Most of them are really simple. Here's one from a common compiler:
long holdrand;

void __cdecl srand (unsigned int seed)
{
    holdrand = (long)seed;
}

int __cdecl rand (void)
{
    return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}
As you can see, it's really really simple.
No rand() in C doesn't return a float from 0 to 1. It returns an int.

Here is an example of a much better PRNG: http://en.wikipedia.org/wiki/Xorshift
Still quite simple, but far far better.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.