Why isn't (rand()%100); totally random?

Started by
11 comments, last by Squeejee 22 years, 6 months ago
I noticed that (rand()%100); isn''t totally random. When I used it, I noticed it repeats the same patern every time. How do the developers make thinks truly random? -----
-----
Advertisement
You need to use the srand function at the beginning of your main function. Include time.h and put this line of code at the beginning:

srand( (unsigned)time( NULL ) );


Edited by - acw83 on October 14, 2001 11:00:46 AM
Without getting seriously bogged down in this whole randomness-issue, let me just say a few things.
First off, you should, as acw points out, call srand in your application. Unless the app is a server or daemon or some such, which will be running for a long time, calling srand once is the way to go.
In any case, rand()%100 is *never* going to be completely random unless you''re lucky enough to have a MAX_RAND (or is it RAND_MAX?) that is evenly divisible by 100. Most likely, however, the difference won''t be very big.

Also, PC''s *cannot* create random numbers. Period. To do so you would need specialized hardware (or a TV/radio-card in your computer and enough knowledge about it to write a weird device-driver). The method mostly used to generate pseudorandom numbers on PC''s (which is also the method used by rand) is something called linear congruency. Basically the rand and srand functions look something like this:
  static unsigned long seed = 0;static const int a = /* SOMETHING */ ;static const int b = /* SOMETHING */ ;static const int RAND_MAX = /* SOMETHING */ ;void srand (unsigned long s) {    seed = s;}unsigned long rand() {    seed = seed * a + b mod RAND_MAX;    return seed;}  

RAND_MAX, by the way, is defined in stdlib.h as 0x7fff (I think).

All of this basically means that even if you do seed the pseudorandom-number-generator you will still get cycles in the returned values, but hopefully cycles of length ~RAND_MAX.

-Neophyte
Another trick used to obtain a fair amount of randomness is to seed the random number generator with the most random number available to the developer - the system time in seconds.

Keep in mind, though, that the psuedo-randomness of rand() can be a positive attribute: if you save the seed, then you can generate the exact same sequence by re-seeding the generator with the saved seed. This feature is extremely useful for instant replays (just remember to save the user inputs!)
MSVC's srand/rand looks like this:
    static long holdrand = 1L;void srand (unsigned int seed) {  holdrand = (long)seed;}int rand (void) {  holdrand = holdrand * 214013L + 2531011L;  return ((holdrand >> 16) & 0x7fff);}    

If you're interested in that type of stuff . No, I have no idea how the person who gave me that code figured it out. You can download GCC's srand/rand source if you're bored .

[Resist Windows XP's Invasive Production Activation Technology!]

Edited by - Null and Void on October 14, 2001 12:42:30 AM
im pretty sure that thr random function, regardless of a pc''s abilities, was designed to be repeatible- to allow multiple, identical demonstrations of (scientific) experiments. bascially, the point was not to be completely random, but to generate amounts of ''carelessness'' in the program.

one thing you might want to do is save ur last random number to file, and use it with the time to make a seed next time ur program runs.

or, maybe fetch the contents of various random memory locations, and make a seed, though this can be unreliable.

if your really anal, you could create your own list of random numbers and use them to suppliment whatever other methods you want.

or, maybe you could accuire the microphone, or some other device, and get some (potentially) truly random input.

you can always combine various methods, though the randomness wont nessecarily be increased. - - you need to really test methods/ combinations to determine their use. sometimes combining methods will reduce randomness, or create huge, easily detectible sequences in your pattern.
quote:Original post by Oluseyi
Another trick used to obtain a fair amount of randomness is to seed the random number generator with the most random number available to the developer - the system time in seconds.

Keep in mind, though, that the psuedo-randomness of rand() can be a positive attribute: if you save the seed, then you can generate the exact same sequence by re-seeding the generator with the saved seed. This feature is extremely useful for instant replays (just remember to save the user inputs!)


Geeez didn''t think of that before. Very interesting!

''saving the seed'' is also kinda what people dit with Elite.
That game had an almost infinite huge galaxy with planets and stars etc etc. This galaxy was always the same, but could not be stored into the 16KbRam or 16Kb Rom, machines had those days.
So, using the same seeds dit the trick.

Gr,
BoRReL
quote:Original post by Null and Void
No, I have no idea how the person who gave me that code figured it out. You can download GCC''s srand/rand source if you''re bored .


The source for MSVC++'' CRT is supplied with it.



"A society without religion is like a crazed psychopath without a loaded .45"
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
quote:Original post by Arild Fines
The source for MSVC++'' CRT is supplied with it.

Really? Now I have to go look at the CD (it doesn''t seem to be installed with the typical setting) .

[Resist Windows XP''s Invasive Production Activation Technology!]
By the way, for some inexplicable reason (at least I''ve never managed to figure out why) the high-order bits of the number returned by rand is more random than the low-order bits.
Paraphrasing the unix man-page on rand:
"If you want to generate a random integer between 1 and 10, you should always do it by
j = 1+(int)(10.0*rand()/RAND_MAX+1.0));
and never by anything resembling
j=1+((int)(1000000.0*rand()) % 10);
(which use the lower-order bits)"

-Neophyte

This topic is closed to new replies.

Advertisement