Skip to main content
GameDev.net gamedev.net
🔒 Locked

How to get a random number between 1 - 52

Started by luasitdown Feb 4, 2006 at 7:04 AM 16 replies 2.1k views
Original Post
luasitdown
luasitdown
//srand(i) ; int ii =rand()%52; do the work? any better way?
haegarr
haegarr
int ii = rand()%52;
produces an integer pseudo random number between 0 inclusive and 52 exclusive.

int ii = rand()%53;
produces an integer pseudo random number between 0 inclusive and 52 inclusive.

float ii = (((float)rand())/RAND_MAX)*52;
produces a floating point pseudo random number between 0 and 52 inclusive (I think, but I'm not sure; perhaps it is exclusive). The resolution depends on RAND_MAX, of course.
Winegums
Winegums
int ii =(rand()%51) + 1;

should make a random number between 0 and 51, then add one to it (giving you the range of 1-52.

may not work, but quite sure it does.
Shaku22
Shaku22
does this help?
#include<iostream.h>#include<ctime>//needed to seed time#include<conio.h>//uses getch functionint main(){    srand(time(0)); //seeds computers clock time to random generator        //any number divided by 6 will return a remainder b/n 0 and 5    int die = (rand() % 6) + 1; //returns a number between 1 and 6            cout<<die<<endl;    getch();//waits for user to press enter before closing}


Quote:

should make a random number between 0 and 51, then add one to it (giving you the range of 1-52.

wrong. it returns a number from 0 and 50 then adding 1 makes it go from 1-51
nullsquared
nullsquared
Make a function or macro for rand:
template<typename T> Random(const Type &Max, const Type &Min = (Type)0) {    return ((Type)(((Type)rand() % (Max - Min)) + Min));}


Then use it with:
int i = Random(52, 1);


It just takes the range and makes a random number between that, and to make it instead from 0 to range to min to max you add min.

This is templated so it should work with doubles, floats, ints, etc. [EDIT] I think that it would work with only int's because of the '%' operator.[/EDIT]

[Edited by - agi_shi on February 4, 2006 10:54:21 AM]
Razorguts
Razorguts
Quote:
Original post by Winegums
int ii =(rand()%51) + 1;

should make a random number between 0 and 51, then add one to it (giving you the range of 1-52.

may not work, but quite sure it does.

This shouldn't work, as the sample space from which the random number is drawn is still 0-51 (and thus the probabilities are skewed) - you'd never be able to randomly generate the number 52.

For example, I want a random number between 1 and 5. If I then add 3 to that number, it doesn't change my sample space to 1-8. And the #s 6, 7, and 8 would never be chosen.

Regards,
AB HarrisEngineer, RG Studios
nobodynews
nobodynews
Quote:
Original post by agi_shi
Make a function or macro for rand:
*** Source Snippet Removed ***

Then use it with:
int i = Random(52, 1);


It just takes the range and makes a random number between that, and to make it instead from 0 to range to min to max you add min.

This is templated so it should work with doubles, floats, ints, etc.


I can't find anything to back me up on this, but I thought the mod operator only worked with integer types and not floats or doubles and therefore your code wouldn't work for non-integer types. Furhermore, you shouldn't really be using the mod operator for this purpose anyway as the distribution of numbers made this way will likely be skewed to the lower numbers.

Think about it this way: you have 10 lollipops and you want to divide them to 3 people. This means two people can get 3 and one person can get 4. By modding the random number you can cause similar problems.

This page looks good for information about random numbers and even shows code for the better version at the end:
http://www.daniweb.com/tutorials/tutorial1769.html
C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) ,
nullsquared
nullsquared
Quote:
Original post by nobodynews
Quote:
Original post by agi_shi
Make a function or macro for rand:
*** Source Snippet Removed ***

Then use it with:
int i = Random(52, 1);


It just takes the range and makes a random number between that, and to make it instead from 0 to range to min to max you add min.

This is templated so it should work with doubles, floats, ints, etc.


I can't find anything to back me up on this, but I thought the mod operator only worked with integer types and not floats or doubles and therefore your code wouldn't work for non-integer types. Furhermore, you shouldn't really be using the mod operator for this purpose anyway as the distribution of numbers made this way will likely be skewed to the lower numbers.

Think about it this way: you have 10 lollipops and you want to divide them to 3 people. This means two people can get 3 and one person can get 4. By modding the random number you can cause similar problems.

This page looks good for information about random numbers and even shows code for the better version at the end:
http://www.daniweb.com/tutorials/tutorial1769.html


I'll back you up =D. I forgot about exactly what you just said.
superpig
superpig
Quote:
Original post by Razorguts
Quote:
Original post by Winegums
int ii =(rand()%51) + 1;

should make a random number between 0 and 51, then add one to it (giving you the range of 1-52.

may not work, but quite sure it does.

This shouldn't work, as the sample space from which the random number is drawn is still 0-51 (and thus the probabilities are skewed) - you'd never be able to randomly generate the number 52.

For example, I want a random number between 1 and 5. If I then add 3 to that number, it doesn't change my sample space to 1-8. And the #s 6, 7, and 8 would never be chosen.


I think you're misunderstanding how it's supposed to work. The rand()%51 expression (which should be rand()%52 as Shaku22 pointed out) gives you a random number in the range [0..50]. Adding one to the result effectively shifts the range - shifts, not expands - to [1..51]. Taking your example, adding 3 to a random number drawn from [1..5] shifts the sample space to [4..8], so 6, 7, and 8 will frequently be drawn. It's 1, 2, and 3 that wouldn't be.
Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse
nilkn
nilkn
It might be a good idea to use different algorithms for integers and floating-point numbers:

int intInRange(const int begin, const int end){     if (begin == end)          return begin;       return ((rand() % (abs(end - first) + 1)) + first);}float floatInRange(const float begin, const float end){     if (begin == end)          return begin;     float generator = (float)(rand()/(float)RAND_MAX);     return ((generator*(float)(fabs(end - first))) + first);}
Razorguts
Razorguts
Quote:
Original post by superpig
I think you're misunderstanding how it's supposed to work. The rand()%51 expression (which should be rand()%52 as Shaku22 pointed out) gives you a random number in the range [0..50]. Adding one to the result effectively shifts the range - shifts, not expands - to [1..51]. Taking your example, adding 3 to a random number drawn from [1..5] shifts the sample space to [4..8], so 6, 7, and 8 will frequently be drawn. It's 1, 2, and 3 that wouldn't be.

Ahh, yes yes. My observation was from a pure mathematical sciences perspective, and not a programmer (I'm an engineer, not a coder). And you are correct - I misunderstood the expanding versus shifting.

Thanks for helping me understand. superpig.

One question, though:

Quote:
by superpig
...rand()%52... gives you a random number in the range [0..50].

How does the function rand()%52 yield a random number with an upper bound of 50?

Regards,
AB HarrisEngineer, RG Studios
Atavist
Atavist
Just to emphasize who said that % gives scewed results and offer an alternative:

LOW ORDER BITS FROM RAND:(BAD)
j = min + (rand() % max);

HIGH ORDER BITS FROM RAND:(GOOD)
j = min + (int)(max * rand() / (RAND_MAX+1));


(the good method can cleary work with floating points with the smallest change)
Just because the church was wrong doesn't mean Galileo wasn't a heretic.It just means he was a heretic who was right.
Will F
Will F
I'm guessing you're dealing simulating a deck of cards so this might be overkill, but if you're using c++ boost::random is also a possibility
Sneftel
Sneftel
Quote:
Original post by Razorguts
Quote:
by superpig
...rand()%52... gives you a random number in the range [0..50].

How does the function rand()%52 yield a random number with an upper bound of 50?

Incorrect ninja chop!
Quote:
Original post by superpig
The rand()%51 expression (which should be rand()%52 as Shaku22 pointed out) gives you a random number in the range [0..50].
Frequency
Frequency
How and why did this topic get so large?

(int(rand()*RAND_MAX)%52)+1

If you have an array of 52 cards, though, you'll just want (randomNumber%52) because your array is indexed 0 to 51, not 1 to 52.

EDIT: not quite
It only takes one mistake to wake up dead the next morning.
JohnBolton
JohnBolton
Quote:
Original post by Frequency
(int(rand()*RAND_MAX)%52)+1

If RAND_MAX is a multiple of the range (52, in this case), the result will always be 1.

Atavist has the right idea, but it doesn't work if the number of bits in RAND_MAX is more than half the number of bits in an int.

This topic comes up frequently. The problem is that rand() is usually a poor RNG, so you have to work around it. There are several solutions, but each has problems or restrictions. I suggest using a different RNG (boost::random as Will F suggested, for example).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Nypyren
Nypyren
using MOD (%) to clip an integer can result in a bad statistical distribution. A more sound way is to create a random number from 0 to RAND_MAX, multiply by your desired maximum, then divide by RAND_MAX. If you do this, you will preserve statistical distribution (as close as the original random number generator will guarantee, at least).

I found this out the hard way while writing brute-force solvers during statistics class.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.