127

Possible Duplicate:
Generate Random numbers uniformly over entire range

I want to generate the random number in c++ with in some range let say i want to have number between 25 and 63.

How can I have that?

1
  • this works perfectly even with loops: output = min + (rand() % (int)(max - min + 1)) Commented Nov 25, 2016 at 7:56

6 Answers 6

380

Since nobody posted the modern C++ approach yet,

#include <iostream> #include <random> int main() { std::random_device rd; // obtain a random number from hardware std::mt19937 gen(rd()); // seed the generator std::uniform_int_distribution<> distr(25, 63); // define the range for(int n=0; n<40; ++n) std::cout << distr(gen) << ' '; // generate numbers } 
Sign up to request clarification or add additional context in comments.

10 Comments

If you wonder "what the hack is mt19937 type?!" - A Mersenne Twister pseudo-random generator of 32-bit numbers with a state size of 19937 bits. It is a "wrapper" for the "mersenne_twister_engine" template (cplusplus.com/reference/random/mersenne_twister_engine) with pre-set params.
@Akiva I think, the last is correct. If it's absent from your distribution, you should upgrade your compiler to C++11-compliant one. It isn't a deprecated function, it's a new one. GCC 4.9+ should certainly have it.
Also worth noting that to do this same thing with floats/doubles, one can use std::uniform_real_distribution<>. Great answer!
Note the std::uniform_int_distribution<> is inclusive -- [25,63] in the above example.
@Akiva and @polkovnikov.ph: It's not about upgrading the compiler (GCC has had C++11 support for ages), but about switching to C++11 using the -std=c++11 compiler flag. Since C++11 is not backwards compatible, all standard-complying compilers (GCC, clang,...) require C++11 to be activated explicitly.
|
57

You can use the random functionality included within the additions to the standard library (TR1). Or you can use the same old technique that works in plain C:

25 + ( std::rand() % ( 63 - 25 + 1 ) ) 

4 Comments

Note that this answer does not generate equally-likely numbers! The below answer is a better approach.
@GeorgeHilliard why? i really does not know, how the algorithm for generating random numbers work
@milanHrabos an example will easily make that clear: std::rand() returns equally distributed integers from 0 to RAND_MAX (inclusively). Now, assuming you obtained integers in the range from 0 to RAND_MAX - 1 (inclusively) by using std::rand() % RAND_MAX, the chance of getting a 0 would now be doubled, since it will be the result when std::rand() returns either 0 or RAND_MAX. Any other number will only be obtained when directly returned by std::rand(). This will apply similarly, for every modulo that is not a divisor of RAND_MAX + 1.
@GeorgeHilliard "Below" is relative.
38
int range = max - min + 1; int num = rand() % range + min; 

7 Comments

Bad advice. This will not yield a uniform distribution. It is a fairly common approach though (but fundamentally flawed).
Why is this flawed? If rand() % range is relatively uniform, I would expect that adding a constant would preserve uniformity. Or are you saying that rand() itself isn't a great choice for a truly random number? That's true, but depending on what OP wants to do, rand() may be sufficient.
@Anson: The reason that Johannes Rudolph is complaining is that % does not work unless the value on the right is an exact divisor of RAND_MAX. If it is not then some values have a slight (very slight) smaller probability. example: RAND_MAX (32767) r = rand()%3; Probability of 0(10923/32767) 1(10922/32767) 2(10922/32767) Notice the probability of a 0 is slightly higher. As 'Benjamin Lindley' points out this is insignificant in most situations but when you do things like cryptography things like this become a problem. Thus a lot of people cry foul when this method is used.
Also there was a problem with the bottom few bits of rand() not being very random (thus if max-min is small you don't get good values (this may have been fixed)). The alternative being num = rand() * 1.0 / RAND_MAX * (max-min+1) + min;
@MartinYork your alternative is no better, it still suffers from the pigeonhole problem, it's just not as obvious why.
|
31
int random(int min, int max) //range : [min, max] { static bool first = true; if (first) { srand( time(NULL) ); //seeding for the first time only! first = false; } return min + rand() % (( max + 1 ) - min); } 

5 Comments

Hope you don't mind the edit, I'm pretty sure that was your intent.
For this to be inclusive of max you have to use max - min + 1
Does it include a range between negative to positive?
Use "return min + rand() % (max + 1 - min);" to obtain the max value itself! =D
rand() returns only numbers in band [0;RAND_MAX]. If (max - min) > RAND_MAX, you never got numbers in range (RAND_MAX; max - min). RAND_MAX is implementation details, but usually equals 7FFF.
10

Use the rand function:

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

Quote:

A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range: ( value % 100 ) is in the range 0 to 99 ( value % 100 + 1 ) is in the range 1 to 100 ( value % 30 + 1985 ) is in the range 1985 to 2014 

4 Comments

@Tux-D That was a code snippet copied straight from the cplusplus website so I guess I figured it was the standard way of doing it. I didn't realize it was incorrect or uncommon to do this way, thanks for the info. Because now I'm curious, what exactly is the problem with this method?
See Benjamin Lindley answer above and my associated comments for the pre-C++11 approach. But my comment above was wrong (I miss read your answer). So I will delete it. The website cplusplus.com is OK bit I (and good for quick reference now and then) but I would NOT use it as an authoritative source.
Thanks for the information. I read the information above and feel I have a better understanding. I would argue that while my answer isn't the best possible answer, it's not NOT useful. But that's your decision and I thank you again for enlightening me. :)
3
float RandomFloat(float min, float max) { float r = (float)rand() / (float)RAND_MAX; return min + r * (max - min); } 

4 Comments

That's not a uniform distribution. Try putting 7 balls into 3 buckets, such that each bucket has the same amount of balls. You're doing exactly the same.
I actually think its correct, its multiply a range by a number in [0,1]. Can you exmplain further @polkovnikov.ph ?
@LorenzoBelli Floats are not uniformly distributed over [0, 1], because they have limited precision. Real numbers are.
Tell me, what's the odds of this algorithm returning max?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.