Sign in to follow this  
Ezbez

Random Number problems

Recommended Posts

Ezbez    1164
Hello, I'd like to be able to do a random interger from, say, minNum to maxNum in c++. Those would both be varaibles. I tried this code: int number = rand()%(maxNum-minNum)+minNum; But it didn't work. Its a little hard to tell what range of number that it did get it for since I emidiatly put it through a sin() function. It does compile without an error and the program doesn't crash or anything. Hopefully that is enough information. Thanks in advance!

Share this post


Link to post
Share on other sites
stylin    758
There was a thread on this exact subject a few weeks ago. Try and do a forum search on "random" or "random numbers" and you should be able to find it (and probably a great deal more).

Share this post


Link to post
Share on other sites
Undeadlnsanity    233
To create generate a random number between 1 and 10 you would use rand()%10+1. To generate a random number between 600 and 750 you would use rand()%750+1. Using something like rand()%100 would give you a random number between 0 and 99, because the null "\0" takes up one slot.

rand() will only give you a random number at comiletime though, so if it generates 15 the first time, everytime you run the program it will still generate 15. Using the ctime header and the srand() function you can achieve run-time random numbers. Here's an example of how to:
#include <iostream> // Text I/O
#include <cstdlib> // Rand and srand
#include <ctime> // Time func in srand

using namespace std;

int main()
{
srand((unsigned)time(NULL)); // Set srand using system time
cout<<rand%10+1; // Print random number between 0 and 10. We could have also used rand%11 here.
}

Share this post


Link to post
Share on other sites
Ezbez    1164
Thanks for the replies.

Stylin: I found that post, but when I used the code, it did not work. I used:
rand () * (max-min) / RAND_MAX) + min;

But that generates random numbers at intervals for some reason. It seemed that it was only giving me multiples of about 5 when I used between 10 and 45.

UndeadInsanity: I'm trying to use variables to determine the range, not preset values.

Okay, heres the whole story:

I'm trying to make random number in a range of angles. This is for some explosions in my game. So sometimes I may want a full complete explosion that goes all the way from 0 degrees to 360 degreees. Other times I may want to just use from 10 degrees to 45 degrees. I would like to use the same function for both of those purposes, and not have to have many seperate ones.

I just made it so that I output(using printf(); ) the randomly generated number, but somethings messed up. Every single output is 2292944. Obviously, this isn't inside of my range. Anyone know whats happening?

What makes this even more mysterious is that while in the game, it appears to be generating random numbers.

Share this post


Link to post
Share on other sites
tj963    234
The above has some errors. Your equation is correct, to genearate number between 600 and 750 you would have

int number = rand()%(750-600)+600;

which would include 600, but not 750, so you'd have 600-749. rand() returns numbers from 0-RAND_MAX, where RAND_MAX is usually equal to the largest number you can put in a signed int (0x7FFFFFFF). Also 'null "\0"' is nonsense, but I assume he's just talking about 0 possibly being returned from rand(). Finally, rand() does not generate numbers at compile time. Every call to rand() will return a different number, but if you don't use srand(), you'll get the same sequence of numbers everytime you run your program. As for you error, my only guess is that sin takes values in radians and you're passing it values in degrees.

tj963

EDIT:
rand () * (max-min) / RAND_MAX) + min;

doesn't really work because of precision issues, and I would use the one above. The distribution is not quite uniform, but unless your creating random numbers from on a range of of millions, or are writing some sort of statistics package I wouldn't worry. Also, my comment about degrees/radians is your problem. As for printf, you might have incorrect parameters.

Share this post


Link to post
Share on other sites
DeadXorAlive    535
I did something similar, maybe this is what you're looking for?

srand((unsigned int)time(NULL)); //seed rand() with time

void RandomRange (int& min, int& max)
{
int a = 0;
int b = 0;

while (a==b) //So that there won't be a range between the same numbers.
{
a = rand() % (360 - 1);
b = rand() % (360 - 1);

if (a > b)
{
max = a;
min = b;
}
else
{
max = b;
min = a;
}
}
}


Nice small tutorial

Share this post


Link to post
Share on other sites
arm    164
Also beware of the quality of random numbers that come from rand(). In some cases RAND_MAX is defined as 0x7fff and the period/distribution of the numbers can be poor depending on the implementation. Quite a lot of the time this doesn't matter but it can cause problems when you start using the modulo ('%') operator which just amplifies the poor quality of the numbers.

arm.

Share this post


Link to post
Share on other sites
DeadXorAlive    535
Quote:
Original post by arm
Also beware of the quality of random numbers that come from rand(). In some cases RAND_MAX is defined as 0x7fff and the period/distribution of the numbers can be poor depending on the implementation. Quite a lot of the time this doesn't matter but it can cause problems when you start using the modulo ('%') operator which just amplifies the poor quality of the numbers.

arm.


I didn't quite get that. Would you or anybody else be so kind to explain how that works and / or affects 'poor quality'? What does 'poor quality' mean in this context?

Share this post


Link to post
Share on other sites
arm    164
Calm yourself,

By 'poor quality' I'm talking mainly about the randomness or distribution of the numbers output by the generator over the possible range of numbers that it can generate. Although, to a lesser extent I am also referring to period.

As for the modulo operator comment, I once read a paper (which I am currently trying to find) that discouraged the use of the modulo operator in combination with random number generators that suffer from poor uniformity coupled with a limited output range (such as some implementations of rand()).

I myself have experienced this problem, expecially when the range of numbers required is very small. You typically see that one or two values tend to be generated with a much greater frequency.

Hope thats clearer,
arm.

Share this post


Link to post
Share on other sites
_winterdyne_    530
It means that rand() isn't a great function for generating random numbers - the numbers it generates can sometimes 'clump' so if you're needing a certain statistical distribution of results it's sometimes not the best choice.

It's like a die that might roll a lot of 1's.

rand() itself generates a number up to RAND_MAX, by performing a complex calculation on a 'seed' value. (see srand(...))

the result is modulo'd (the remainder of an integer division is returned).
(eg 9%8=1, 15%3=0, 5%3=2)

with a poor set of results, further narrowing the range using modulo arithmetic makes the distribution poorer.

Share this post


Link to post
Share on other sites
DeadXorAlive    535
Ah, thank you very much. So the 'problem' lies in the implementation of rand() then as I understand it. Which may or may not yield a poor statistical distribution depending on your implementation.
I assume boost::random will be better.

EDIT: arm, thanks you for the explanation. Reading over my post, I understand it came across a little aggravated. I wasn't at all, the quotations around 'poor quality' were meant to emphasize I didn't understand what that was referring to, it's a little internet communication problem I'm still not used to.
I understand that randomizing numbers is a complex issue with computers. It's very helpful for me to know these facts to the extend one can use it in gamecode, as I am not that good at math.

Also, sorry if I recommended a bad practice due to me underestimating the complexity of random numbers. I'll try not posting such things in the future when I don't have a grasp of the issue.

Share this post


Link to post
Share on other sites
arm    164
Don't worry about it, its always pretty hard to figure out people's intonation when reading over their posts as opposed to listening to someone in conversation. Looking at my original post, it does seem a bit ambiguous. I wish I could find that paper about the modulo operator.

As for boost, its probably the best option if you need a good random number generator. It actually has a number of very good generators including the Mersenne Twister with its huge 2^19937 period.


Share this post


Link to post
Share on other sites
tj963    234
While everything mention above is true, I wouldn't worry about it unless you're seeing problems. Using rand() will likely be fine for what you're doing, but boost::random is probably your best option if you do need something better.

tj963

Share this post


Link to post
Share on other sites
Inmate2993    222
(int)(((float)rand()/(float)RAND_MAX)*(max-min)+min)

The reason you'd see multiples of 5 is because the truncation due to integer division. Cast the numbers to float first in order to preserve the accuracy.

Share this post


Link to post
Share on other sites
Ezbez    1164
Thanks everyone for posting. I actually got it to work after someone(I'm afraid I can't find the post anymore) said that I should convert it to radians. Sorry for the long time before I posted.

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