Sign in to follow this  
mrm83

random not randoming!

Recommended Posts

i have this code. int num; num = rand()%5; yes, i get a random number for num. BUT, the random numbers are the same everytime i run the program!! im not getting a different set of random numbers! 1st time i get 1 3 4 2, 2nd program run i get 1 3 4 2, 3rd program run i get 1 3 4 2, i keep getting the same set of numbers! why?

Share this post


Link to post
Share on other sites
Just to explain this a little:

Computers are actually really bad at random numbers. Everything about them is built to be deterministic - in general, if you're going to compute something, you want to compute it the same way every time. The C library's rand() function is what's called a "pseudo-random number generator" - it generates a sequence of numbers that seem to be unconnected but are actually the result of following a formula involving assorted large numbers and powers and so on. The result of the formula the first time is used as the input the second time.

What this does mean is that if the input the first time is always the same, then the sequence of random numbers produced will always be the same. This input number is called the 'seed.'

To get around this, you set the seed according to some factor that is likely to be different every time you run the program - time of day, total number of mouse button presses since the system was turned on, whatever you like. time() returns the number of seconds elapsed since the beginning of 1970, and that's always going to be different each time you run your program, so by using time() as the seed you'll always get a different sequence of 'random' numbers.

Note that this does have some convenient side-effects - for example, if you want to implement an 'action replay' feature in your game, you can deliberately set the seed to a particular value to get the same sequence of random numbers each time you run the replay.

It does have its downsides though. Random numbers are often useful in cryptographic applications, and if you can predict what those numbers are going to be then it can make the cryptography easier to crack. That's why you can buy specialist hardware that uses things like radioactive decay to produce much less predictable random numbers.

Share this post


Link to post
Share on other sites
It can be really useful though, to have pseudo-random numbers.

On our game client when a hero attacks and we have to calculate damage.
We use a certain seed (which the server also knows - it can be as simple
as incrementing the seed-number each time we get a damage packet),
and using that seed we start to get several random numbers to do all
calculations for the damage event. The actual damage is displayed (for
quick client responsiveness).

The server will do the same calculation, and since it has the same
seed (an thus sequence of random numbers) both client & server will
get to the same damage (unless the client is hacked, which doesn't
matter since the client only calculated it for displaying and is
actually waiting for server confirmation)

Just my 2ct :)

Share this post


Link to post
Share on other sites
Quote:
Original post by mrm83
oh !
thanks!
ur my hero~

Don't forget to call srand(time(NULL)); only once at the beginning of your program. It is not necessary or wise to call srand before each call to rand.

Share this post


Link to post
Share on other sites
Would it be possible to generate a random value from a range by reading the timestamp counter (RDTSC) and them mod this result with the range you're interseted in

eg.

RandomNumber = (RDTSC % (Highest - Lowest)) + Lowest

Would this make a good RNG for smallish ranges if this is called right after a user presses a key, moves the mouse, etc...


Share this post


Link to post
Share on other sites
That would probably not give you a very random distribution at all. Just use rand(). If the RDTSC was a good source of random values, the people who wrote rand() for your platform would have probably used it themselves anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Adam Hamilton
Would it be possible to generate a random value from a range by reading the timestamp counter (RDTSC) and them mod this result with the range you're interseted in

eg.

RandomNumber = (RDTSC % (Highest - Lowest)) + Lowest

Would this make a good RNG for smallish ranges if this is called right after a user presses a key, moves the mouse, etc...


RDTSC counts the number of instruction cycles between two subsequent calls. As a conclusion, you're very likely to get similar results between two runs of your software, especially if you call it quite often. Moreover, if you really call it often and if (Highest - Lowest) is quite big (let's say... 1,000,000), you'll probably get nearly linear progressions sometimes that will create a pattern in the random number generation (for example, if a small code portion needs 1000 cycles to execute, you're going to get n, n+1000, n+2000, and so on until you get a thread context switch). Patterns like this are Not A Good Thing [smile].

Regards,

Share this post


Link to post
Share on other sites
Quote:
Original post by Kitt3n
And as a sidenote, if your using threads, each thread needs its own seed.


I never thought about rand() and multithreading before,
don't threads share memory and thus share random seed?
so calling from 5 threads would be like calling from one thread 5 times?
I'd understand if you'd said each process needs its own seed.

also, is C rand() threadsafe? or maybe if you run it at the same time from two threads you may ruin the pesudo randomness?

Share this post


Link to post
Share on other sites
Also, it is better to use

(rand() / (RAND_MAX-1)) * N

rather than

rand() % N

The % formula focuses on the lowest bits of the returned valuf of rand(). These values often come from some linear congruential methods, which provides numbers where the lowest bits are less random than the higher ones. So the use of the first formula is recommended.

Share this post


Link to post
Share on other sites
surfi - to access the upper random bits, you can also use the shift operator, assuming you want random numbers within the range of 0 - (2^n - 1).

(unsigned int)rand() >> (sizeof(unsigned int)*8 - n)

For example, if n = 8, you'll get random numbers within the range of 0 - 255.

Quote:
Original post by Emmanuel Deloget
RDTSC counts the number of instruction cycles between two subsequent calls. As a conclusion, you're very likely to get similar results between two runs of your software, especially if you call it quite often. Moreover, if you really call it often and if (Highest - Lowest) is quite big (let's say... 1,000,000), you'll probably get nearly linear progressions sometimes that will create a pattern in the random number generation (for example, if a small code portion needs 1000 cycles to execute, you're going to get n, n+1000, n+2000, and so on until you get a thread context switch). Patterns like this are Not A Good Thing [smile].

Regards,

RDTSC represents the number of clock ticks since the machine was powered on, assuming the 64-bit counter did not overflow. To get the number of instruction cycles between two subsequent calls, you'd have to save the value from the last RDTSC call and find the difference at the next call.

Having said that, RDTSC may be an OK source for setting the initial seed though.

[Edited by - Tachikoma on March 12, 2007 9:53:16 PM]

Share this post


Link to post
Share on other sites
I borrowed this idea of using a timer for generating random number generators from programming PIC microcontrollers.

When I meant smallish ranges, I didn't exactly mean numbers from 1 to 1,000,000 although this would still overflow in a microsecond or so.

You would get a linear progression if called repeatidly but I was meaning that this be called in combination with other events generated by a user.

In D&D type games... Lets say you have a character and you want to set the agility and hit points. You could click on the button and because your range is quite small in this case I bet you that the result will be truely random. There will be no linear progression of values unless the user can click the button every 30-40 nanoseconds.

This is all I meant for an alternate RNG.

Share this post


Link to post
Share on other sites
It's an interesting idea, but I bet there is still not as random a distribution as you would get with your system's rand(). On embedded systems that don't provide rand(), that might be the best method that requires little effort.

Share this post


Link to post
Share on other sites
Just a thought... if you use Putty to generate a certificate, it uses the mouse to generate random "noise" to use as random fodder. Wonder if that would be something worthwhile in a game: have the menu mouse-driven, and record the total movement of the mouse in some way to get your random seed.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this