How to Generate Random Numbers in C++ With a Range
6 Answers 6
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 }
answered Sep 26 '11 at 19:54
CubbiCubbi
44.3k 13 gold badges 95 silver badges 161 bronze badges
7
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 ) )
answered Sep 26 '11 at 19:21
K-balloK-ballo
77.6k 19 gold badges 150 silver badges 165 bronze badges
4
-
Note that this answer does not generate equally-likely numbers! The below answer is a better approach.
Mar 28 '14 at 7:23
-
@GeorgeHilliard why? i really does not know, how the algorithm for generating random numbers work
Jul 29 '20 at 21:43
-
@milanHrabos an example will easily make that clear:
std::rand()
returns equally distributed integers from0
toRAND_MAX
(inclusively). Now, assuming you obtained integers in the range from0
toRAND_MAX - 1
(inclusively) by usingstd::rand() % RAND_MAX
, the chance of getting a0
would now be doubled, since it will be the result whenstd::rand()
returns either0
orRAND_MAX
. Any other number will only be obtained when directly returned bystd::rand()
. This will apply similarly, for every modulo that is not a divisor ofRAND_MAX + 1
.Aug 27 '20 at 14:29
-
@GeorgeHilliard "Below" is relative.
Oct 22 at 7:06
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); }
answered Sep 26 '11 at 19:22
NawazNawaz
335k 108 gold badges 637 silver badges 823 bronze badges
5
-
Hope you don't mind the edit, I'm pretty sure that was your intent.
Sep 26 '11 at 19:45
-
For this to be inclusive of max you have to use max - min + 1
Apr 25 '14 at 12:23
-
Does it include a range between negative to positive?
Apr 21 '16 at 21:44
-
Use "return min + rand() % (max + 1 - min);" to obtain the max value itself! =D
Oct 10 '16 at 17:25
-
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.
Oct 17 at 6:56
int range = max - min + 1; int num = rand() % range + min;
answered Sep 26 '11 at 19:21
Benjamin LindleyBenjamin Lindley
97.3k 8 gold badges 185 silver badges 263 bronze badges
7
-
Bad advice. This will not yield a uniform distribution. It is a fairly common approach though (but fundamentally flawed).
Sep 26 '11 at 19:23
-
Why is this flawed? If
rand() % range
is relatively uniform, I would expect that adding a constant would preserve uniformity. Or are you saying thatrand()
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.Sep 26 '11 at 19:32
-
@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.Sep 26 '11 at 20:25
-
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;
Sep 26 '11 at 20:29
-
@MartinYork your alternative is no better, it still suffers from the pigeonhole problem, it's just not as obvious why.
May 8 at 18:37
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
answered Sep 26 '11 at 19:22
Kiley NaroKiley Naro
1,689 1 gold badge 14 silver badges 19 bronze badges
4
-
@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?
Sep 27 '11 at 2:15
-
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.Sep 27 '11 at 3:49
-
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. :)
Sep 27 '11 at 13:18
float RandomFloat(float min, float max) { float r = (float)rand() / (float)RAND_MAX; return min + r * (max - min); }
answered Sep 26 '11 at 19:22
Yurii HohanYurii Hohan
3,821 4 gold badges 36 silver badges 53 bronze badges
4
-
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.
Jan 25 '15 at 0:43
-
I actually think its correct, its multiply a range by a number in [0,1]. Can you exmplain further @polkovnikov.ph ?
Aug 27 '16 at 9:56
-
@LorenzoBelli Floats are not uniformly distributed over [0, 1], because they have limited precision. Real numbers are.
Aug 27 '16 at 19:58
-
Tell me, what's the odds of this algorithm returning
max
?May 8 at 18:41
Not the answer you're looking for? Browse other questions tagged c++ random or ask your own question.
How to Generate Random Numbers in C++ With a Range
Source: https://stackoverflow.com/questions/7560114/random-number-c-in-some-range/7560151
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.Nov 12 '14 at 11:56
@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.
Jan 25 '15 at 0:41
Also worth noting that to do this same thing with floats/doubles, one can use std::uniform_real_distribution<>. Great answer!
Jun 16 '15 at 20:10
Note the
std::uniform_int_distribution<>
is inclusive --[25,63]
in the above example.Sep 23 '16 at 4:20
@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.Oct 27 '16 at 12:34