Archived

This topic is now archived and is closed to further replies.

Squeejee

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

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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!)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Hi, I'm a fairly new programmer, but thought I might as well throw in my comments as well.
You may find a use for a rather interesting mathematical toy called 'hailstone numbers'. Although the idea is very simple hailstone numbers have resisted every mathemeticians attempt to predict their properties from a single starting number. Heres how they work...
From your beginning number (which is an integer of any value), lets call it X- if X is odd do (X x 3 + 1), if X is even do (X / 2), to produce a new value, then apply the rules to the new number to produce the next number and so on. Do this until X is 1. Writing a hailstone function would take 5 minutes.
You will get a long sting of numbers of unpredictable length, with unpredictable maximum and minimum values before eventually getting to 1. The same starting number will produce the same series of values. e.g. starting with 13 as X, you get 40, 20, 10, 5, 16, 8, 4, 2, 1. Try it with 27 as X..
Jon

p.s. very interesting about saving the seeding number in the srand() function and its use in Elite. I always wondered how the hell they squeezed a whole galaxy onto a couple of discs...

Edited by - jonpolly99 on October 17, 2001 1:14:37 PM

Share this post


Link to post
Share on other sites
quote:
Original post by Null and Void

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



I always install everything. Anyway, I have seen it in an installation of VS6 Enterprise and VS.NET Professional. Maybe the standard version doesnt have it, I dont know(Thats what Borland does; the VCL source is supplied only with the Pro and Enterprise versions).



"A society without religion is like a crazed psychopath without a loaded .45"

Share this post


Link to post
Share on other sites