Sign in to follow this  
Antonym

random number?

Recommended Posts

How can I get a random number, specificly a random number between two numbers in C++? I've learnt you need the rand() or rand_s() function(The latter is better isnt it?) though I don't really know how to work with it even less how to get a random number between two numbers with it... If anyone could help me out with this I'd be grateful. Thanks.

Share this post


Link to post
Share on other sites
Why don't you try Googling and reading the material on random number generation in C++?

Also, to have a random number between a set range, you need to do a few mathematical operations. It's not complicated if you think about it. Or look it up online to see the basic formulas.

Share this post


Link to post
Share on other sites
Use the modulo and then offset the outcome, such as:
Let's say you want a "random" number between 13 and 78.

srand(time(0)); // initialize randomizer

int r = rand(); // pick a random number
r = r % 66; // limit that number to between 0 and 65
r += 13; // this will offset it by 13, giving you some number between 13 and 78

Share this post


Link to post
Share on other sites
I've gone ahead and looked into the subject a bit, so rand() isn't the best method to get random numbers? Will this method give me problems in the long run? I require random numbers for simple stuff such as a damage range for attacks, a probability to hit target etc..

Share this post


Link to post
Share on other sites
cause noone said it yet.
call srand(time(0)); ONCE in you code when you want to initalize the random number sequence (ie the top of main)

then call rand() to get your random numbers.
You can also get a good random distribution between two numbers with:

float range = highNum - lowNum;
float num = ((float)rand() / (float)RAND_MAX) * range + lowNum;

Share this post


Link to post
Share on other sites
Quote:
Original post by Antonym
I've gone ahead and looked into the subject a bit, so rand() isn't the best method to get random numbers? Will this method give me problems in the long run? I require random numbers for simple stuff such as a damage range for attacks, a probability to hit target etc..


for a thing like damage or probability you're a better shot with computing it based on some data rather than random'ing, random() isn't that much random as you think. Set srand(time(0)) as I said before, put it at the beginning of your main or whatever so it initializes the randomizer based on current time, this will give you less chance on the numbers repeating.

Share this post


Link to post
Share on other sites
Note that using modulus (%) can have bad consequences based on the underlying implementation of rand(). Many implementations use an LCG or other similar type of pseudo-random generator, which may result in a low order of "randomness" in the lower bits of the value, so that naively taking the modulus of the result can be bad. (For instance, many LCG implementations will return alternately even/odd results, so that the final results of a mod operation will also alternate even and odd). Even higher order PRNGs frequently exhibit a low amount of randomness in the lower order bits.

A better way is to normalize the result before scaling to a range. rand() returns a value in the range [0..RAND_MAX), so casting the result to a double and dividing by RAND_MAX+1 returns a number in the range [0,1) (ie, approaching 1 but never actually reaching 1) which you can then scale and truncate into any desired integral range, [Low, High]:

double d=(double)rand() / ((double)RAND_MAX + 1.0);
int roll=(int)(Low + d*(High-Low));

You can also bit-shift the result of rand() a few places before taking the modulus, although this can reduce the period of the sequence, or amount of time before the values repeat themselves.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antonym
I've learnt you need the rand() or rand_s() function(The latter is better isnt it?)


Not really; it's Microsoft-specific.

There's nothing magical about any of the formulas you're being given here. The function gives you a random number across a specific range, and you do math in order to map that into the range that you want. If you Think(TM), you can figure these kinds of things out for yourself.

Share this post


Link to post
Share on other sites
'for a thing like damage or probability you're a better shot with computing it based on some data rather than random'ing, random() isn't that much random as you think.Set srand(time(0)) as I said before, put it at the beginning of your main or whatever so it initializes the randomizer based on current time, this will give you less chance on the numbers repeating.'

What do you mean? Setting srand(time(0)) will solve any expected problems? Will allow me to use srand for what I want?


'A better way is to normalize the result before scaling to a range. rand() returns a value in the range [0..RAND_MAX), so casting the result to a double and dividing by RAND_MAX+1 returns a number in the range [0,1) (ie, approaching 1 but never actually reaching 1) which you can then scale and truncate into any desired integral range, [Low, High]:

double d=(double)rand() / ((double)RAND_MAX + 1.0);
int roll=(int)(Low + d*(High-Low));

You can also bit-shift the result of rand() a few places before taking the modulus, although this can reduce the period of the sequence, or amount of time before the values repeat themselves.'

What...? That made me feel so noob.

Share this post


Link to post
Share on other sites
srand(param) is a funtion that initializes the randomizer (random number generator) with given value, because computing random numer is and isn't what it says: it is computing some number given some initial parameter, so you understand that it is not truly random.
srand(time(0)) initializes it with current time, so that each time you initialize the randomizer, you initialize it with a different initial param (called "seed").
Give it a try, put srand(0) and then output few rand() calls. Run the program few times and the numbers will repeat, as you're initializing with the same value. Setting srand(time(0)) sets a different seed for the randomizer each time the program will run, making the numbers somewhat more... "random".

Share this post


Link to post
Share on other sites
Quote:
Original post by Antonym'A better way is to normalize the result before scaling to a range. rand() returns a value in the range [0..RAND_MAX), so casting the result to a double and dividing by RAND_MAX+1 returns a number in the range [0,1) (ie, approaching 1 but never actually reaching 1) which you can then scale and truncate into any desired integral range, [Low, High]:

double d=(double)rand() / ((double)RAND_MAX + 1.0);
int roll=(int)(Low + d*(High-Low));

You can also bit-shift the result of rand() a few places before taking the modulus, although this can reduce the period of the sequence, or amount of time before the values repeat themselves.'

What...? That made me feel so noob.
The function rand() by itself returns a number between 0 and RAND_MAX, a constant defined in cstdlib which we'll say is 32767 (it may be higher). If you just do something like this:
int randNum = rand() % 10000;
Then the chances of getting a number between 0 and 2767 are much higher than the chances of getting a number between 2768 and 9999. Note that there are 4 ways for the result to be 2000 (2000, 12000, 22000, and 32000), while there are only 3 ways that the result could be 3000 (3000, 13000, and 23000).

That's what he meant in the first part - it doesn't really produce a uniform distribution of random numbers. Normalizing the result to produce a decimal between 0 and 1, and then applying a scale and offset makes the distribution of random numbers more uniform.

My example uses a very large range. For small ranges, however, it's a pretty reasonable approximation.

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