C++ Random Numbers

Bob 3 Tallied Votes 52K Views Share

Intro

This tutorial provides a brief introduction to the random number functions that come as part of the C++ standard library, namely rand() and srand().

rand() and RAND_MAX

The C++ standard library includes a pseudo random number generator for generating random numbers. In order to use it we need to include the <cstdlib> header. To generate a random number we use the rand() function. This will produce a result in the range 0 to RAND_MAX, where RAND_MAX is a constant defined by the implementation.

Here's a piece of code that will generate a single random number:

#include <cstdlib> 
#include <iostream>

using namespace std;

int main() 
{ 
    int random_integer = rand(); 
    cout << random_integer << endl; 
}

The value of RAND_MAX varies between compilers and can be as low as 32767, which would give a range from 0 to 32767 for rand(). To find out the value of RAND_MAX for your compiler run the following small piece of code:

#include <cstdlib> 
#include <iostream>

using namespace std;

int main() 
{ 
    cout << "The value of RAND_MAX is " <<  RAND_MAX << endl; 
}

srand()

The pseudo random number generator produces a sequence of numbers that gives the appearance of being random, when in fact the sequence will eventually repeat and is predictable.

We can seed the generator with the srand() function. This will start the generator from a point in the sequence that is dependent on the value we pass as an argument. If we seed the generator once with a variable value, for instance the system time, before our first call of rand() we can generate numbers that are random enough for simple use (though not for serious statistical purposes).

In our earlier example the program would have generated the same number each time we ran it because the generator would have been seeded with the same default value each time. The following code will seed the generator with the system time then output a single random number, which should be different each time we run the program.

#include <cstdlib> 
#include <ctime> 
#include <iostream>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer = rand(); 
    cout << random_integer << endl; 
}

Don't make the mistake of calling srand() every time you generate a random number; we only usually need to call srand() once, prior to the first call to rand().

Generating a number in a specific range

If we want to produce numbers in a specific range, rather than between 0 and RAND_MAX, we can use the modulo operator. It's not the best way to generate a range but it's the simplest. If we use rand()%n we generate a number from 0 to n-1. By adding an offset to the result we can produce a range that is not zero based. The following code will produce 20 random numbers from 1 to 10:

#include <cstdlib> 
#include <ctime> 
#include <iostream>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    for(int index=0; index<20; index++){ 
        random_integer = (rand()%10)+1; 
        cout << random_integer << endl; 
    } 
}

A better method, though slightly more complicated, is given below. This overcomes problems that are sometimes experienced with some types of pseudo random number generator that might be supplied with your compiler. As before, this will output 20 random numbers from 1 to 10.

#include <iostream> 
#include <ctime> 
#include <cstdlib>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    int lowest=1, highest=10; 
    int range=(highest-lowest)+1; 
    for(int index=0; index<20; index++){ 
        random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
        cout << random_integer << endl; 
    } 
}

Conclusion

If you need to use a pseudo random number generator for anything even remotely serious you should avoid the simple generator that comes with your compiler and use something more sophisticated instead. That said, rand() still has its place and you may find it useful.

camelNotation 1 Posting Whiz in Training

I hate to be forced to pm you so many times Bob but In my internet explorer browser the font of your webpage is as small as ants and I don't know how to make them look bigger.
About this tutorial , I would like to know what is the " actual " use of random number generating.

Bob 15 using namespace Bob Team Colleague

Thanks for the feedback about the font size on my web site. I wasn't aware that anyone had a problem with it till now. I'll look into it. Perhaps you could let me know what your screen resolution is set to, or anything else that you feel might be relevant. Is the font too small on all of the pages? Time is short right now but in the near future I'll try to come up with a generic solution. In the meantime, the content is available as a PDF download from the site, or can be sent out via email.

As for the use of generating random numbers, well almost any use really. For example, someone might simulate rolling a dice in their program, generating numbers in the range 1 to 6, or have an array of character strings and generate them seemingly at random by generating a random number within the range of valid indexes for the array. A lottery program might generate numbers using rand(). Almost anything you can think of, but remember that the random number generators that ship with compilers are usually pretty basic and not adequate for serious applications, e.g. scientific or crypto use. Better generators are available.

aylina 0 Newbie Poster

This tutorial provides a brief introduction to the random number functions that come as part of the C++ standard library, namely rand() and srand().

rand() and RAND_MAX

The C++ standard library includes a pseudo random number generator for generating random numbers. In order to use it we need to include the <cstdlib> header. To generate a random number we use the rand() function. This will produce a result in the range 0 to RAND_MAX, where RAND_MAX is a constant defined by the implementation.

Here's a piece of code that will generate a single random number:


#include <cstdlib>

#include <iostream>

using namespace std;

int main()
{
int random_integer = rand();
cout << random_integer << endl;
}


The value of RAND_MAX varies between compilers and can be as low as 32767, which would give a range from 0 to 32767 for rand(). To find out the value of RAND_MAX for your compiler run the following small piece of code:

#include <cstdlib>

#include <iostream>

using namespace std;

int main()
{
cout << "The value of RAND_MAX is " << RAND_MAX << endl;
}


srand()


The pseudo random number generator produces a sequence of numbers that gives the appearance of being random, when in fact the sequence will eventually repeat and is predictable.

We can seed the generator with the srand() function. This will start the generator from a point in the sequence that is dependent on the value we pass as an argument. If we seed the generator once with a variable value, for instance the system time, before our first call of rand() we can generate numbers that are random enough for simple use (though not for serious statistical purposes).

In our earlier example the program would have generated the same number each time we ran it because the generator would have been seeded with the same default value each time. The following code will seed the generator with the system time then output a single random number, which should be different each time we run the program.


#include <cstdlib>

#include <ctime>
#include <iostream>

using namespace std;

int main()
{
srand((unsigned)time(0));
int random_integer = rand();
cout << random_integer << endl;
}


Don't make the mistake of calling srand() every time you generate a random number; we only usually need to call srand() once, prior to the first call to rand().


Generating a number in a specific range

If we want to produce numbers in a specific range, rather than between 0 and RAND_MAX, we can use the modulo operator. It's not the best way to generate a range but it's the simplest. If we use rand()%n we generate a number from 0 to n-1. By adding an offset to the result we can produce a range that is not zero based. The following code will produce 20 random numbers from 1 to 10:


#include <cstdlib>

#include <ctime>
#include <iostream>

using namespace std;

int main()
{
srand((unsigned)time(0));
int random_integer;
for(int index=0; index<20; index++){
random_integer = (rand()%10)+1;
cout << random_integer << endl;
}
}


A better method, though slightly more complicated, is given below. This overcomes problems that are sometimes experienced with some types of pseudo random number generator that might be supplied with your compiler. As before, this will output 20 random numbers from 1 to 10.

#include <iostream>

#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=10;
int range=(highest-lowest)+1;
for(int index=0; index<20; index++){
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;
}
}


If you need to use a pseudo random number generator for anything even remotely serious you should avoid the simple generator that comes with your compiler and use something more sophisticated instead. That said, rand() still has its place and you may find it useful.


my question is, for the functions on choosing random numbers in a specific range, what should i do to make the cout one by one?
As in, like the function given above, it gives the whole 20 outputs at once, but what i would like to do is to get the output one by one, how could i do that?
and let's say i have a range from 2 to N, what should i do to get the output only from 2 to N and not 0 to N?because what's given in the previous thread is a function to choose from 0 to N.
thank you :D

jyeshta 0 Newbie Poster

Hi BOb,
Thanks for the random number generator programs.
I want to experiment with true random number generator and need a program that runs by a input through the keyboard or soundcard. that is a word or a noise - a wave file. I must get the numbers from 00 to 99 each one from every decade. e.g, oo,13,24,37,49,52,65,73,88,91;
Please send me your tutorial on this through my e-mail also.
Thanks and best regards, Bob,
Jyeshta

jyeshta 0 Newbie Poster

Hi Bob,
Good day,
I tried to execute the program[last one] you presented there in the random number generator file. I have TURBOC 30 which is C++ compiler and says that it don't have i0stream, and the other two header files, Will you please send them to me? I tried to install Boreland C++ but it is not showing the compiler . When I click on the icon it just appears and dissappears. I have windows XP and don't know how to solve these problems. Your help is highly appreciated,
Thanks and best regards, BOb,
Jyeshta

blackshadow05 0 Newbie Poster

Hey,

Ive been playing around with your random number generator and I have a couple questions, first I was wondering how can i make it where numbers can't repeat themselves, to put every number in once. The second question is, is there any code that you can put in names nd generate them in random order.

Thanks

1o0oBhP 4 Posting Pro in Training

how can i make it where numbers can't repeat themselves

one way is to track what numbers are generated and save them in an array for instance. then check back to see if it is already generated.... IMHO if you have a range of over 50 then the numbers are going to still be random and its unlikely to get repeats. you could always get two random numbers in succession and multiply / add / whatever so that the combined numbers vary a bit more.

is there any code that you can put in names nd generate them in random order

put names in an array, generate random numbers from 0 to the size of the array - 1. make sure of no repeats and then store the numbers in a separate array so you might have:

"Bill"
"Bob"
"James"
"Chris"
"Thomas"

so you would generate numbers from 0 to 4 and might get:

3
1
4
0
2

in a separate array. Then copy across from the string array the string at the index specified by the second array. Then it becomes:

"Chris"
"Bob"
"Thomas"
"Bill"
"James"

Hope this helps :)

evilsilver 0 Junior Poster in Training


my question is, for the functions on choosing random numbers in a specific range, what should i do to make the cout one by one?
As in, like the function given above, it gives the whole 20 outputs at once, but what i would like to do is to get the output one by one, how could i do that?
thank you :D

one way to do this is to use the getch(); you can put it in the for loop right after the cout command. this will have the computer pause after each display of the number, pressing any key will make the computer continue. (you will also have to include #include <conio> to run the getch(); function.)
for example:

#include <iostream>
#include <conio>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=10;
int range=(highest-lowest)+1;
for(int index=0; index<20; index++){
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;
getch();
}
}
evilsilver 0 Junior Poster in Training

Hi Bob,
Good day,
I tried to execute the program[last one] you presented there in the random number generator file. I have TURBOC 30 which is C++ compiler and says that it don't have i0stream, and the other two header files, Will you please send them to me? I tried to install Boreland C++ but it is not showing the compiler . When I click on the icon it just appears and dissappears. I have windows XP and don't know how to solve these problems. Your help is highly appreciated,
Thanks and best regards, BOb,
Jyeshta

I use Borland aswell (i like it personally) as for the compiler it is just the play button (labeled as run) and when you say you click on the icon and it dissapears right away, are you talking about the Borland program itself, or the program you are trying to run? if it is the program it is because the computer is executing the program then seeing that there is nothing else to do closes itself. if you #include <conio> you can use the getch(); command at the end of your program which will keep the window open until you press anykey then it will close.

paskal 0 Newbie Poster

Hi!
How to access random numbers one by one? Say calling random number 7 to be used by another function.

Naveen 4 Light Poster

Hi Bob.

I just wanted to know if random() could be included in ur list of random no generating functions as well.

random works as a macro and a function:
Macro: random( int num )
Function : int random( int num )

In both cases a random number between 0 and num-1 is generated.

Also we use randomize() before we call rand()/random(). Any reason for that?

Regards,
Naveen.

Attendant 0 Newbie Poster

Hello all,

I'm new to the daniweb forums, as well as C++. I've decided to make a "slot machine" program... however the code for the random number is kind of messy.

I've decided to use a [3][3] array to store the #'s, and this is how I currently have it set up:

slots[1][1] = rand()%9;
slots[1][2] = rand()%9;
slots[1][3] = rand()%9;
slots[2][1] = rand()%9;
slots[2][2] = rand()%9;
slots[2][3] = rand()%9;
slots[3][1] = rand()%9;
slots[3][2] = rand()%9;
slots[3][3] = rand()%9;

as you can see this is the long-hand way... is there a better way to assign the "rand()%9;" command?

peace,

winkland 0 Newbie Poster

is there a better way to assign the "rand()%9;" command?

peace,

This may not be better, but it is shorter

for (int a=1; a<4; a++){
for(int b=1; b<4; b++){
slots[a] = rand()%9; OR slots[a]=( rand() *10 ) +1; //this assumes you wanted 1-10
}
}

perut_macho 0 Newbie Poster

plzz i need some help!!how can i generate 100 unique integer random
numbers in[1000, 9999] in array list, then how may i know how many of these fall in the range 1000-2500, 2501-5000, 5001-7500 and 7501-9999?

bucsoldier03 0 Newbie Poster

Generate 2 random numbers (call them arraySize1 and arraySize2) within a user-specified range of lower_size_bound to upper_size_bound, inclusive.
Allocate 3 dynamic arrays of integers (called them array1, array2 and arrayCombo) sized arraySize1, arraySize2 and (arraySize1+arraySize2), respectively.
Generate arraySize1 random numbers within a user-specified range of lower_value_bound to upper_value_bound, inclusive, and store each value (as soon as it is generated) into array1 using the StoreOrdered function (non-decreasing order) developed in class.
Generate arraySize2 random numbers within the range of lower_value_bound to upper_value_bound, inclusive, and store each value (as soon as it is generated) into array2 using the StoreOrdered function (non-decreasing order) developed in class.
Copy the values in array1 and array2 into arrayCombo using the CombineOrdered function developed in class.
Output the values in arrayCombo in the form of a frequency plot for a user-specified range_width as illustrated below (the number of asterisks on each line is the number of values that fall within the indicated range) using a PlotArray function that you must develop:

pokerponcho 0 Newbie Poster

This will shuffle integers aound anyway you like. So if you had an array that represented a deck of cards called "deck[]", you would call the function like this:

shuffle(&deck, 52, 0, 0);

This will give you a series of random cards from 0 to 51. The trick is to randomize the place to put the card in rather than to randomize the card. That's why I used pointers. It's not a matter of if you put an ace of spades, it's a matter of whether it should be the 4th or the 40th.

void shuffle(int *array_ptr, int len, int def, int min) {
int i = 0;
int temp;
for (i = min; i < len; ++i) {
*(array_ptr + i) = def; // 'zero' the array
}
srand((unsigned)time(0)); // set an srand
while (i < len) { // while not done shuffling
temp = rand() % len + min; // get a random integer between min and len
if (*(array_ptr + temp) == def) { // if nothing in the element yet
// put i into element
*(array_ptr + temp) = i;
++i; // incrament i
}
}
}
elina 0 Newbie Poster

one way is to track what numbers are generated and save them in an array for instance. then check back to see if it is already generated.... IMHO if you have a range of over 50 then the numbers are going to still be random and its unlikely to get repeats. you could always get two random numbers in succession and multiply / add / whatever so that the combined numbers vary a bit more.

put names in an array, generate random numbers from 0 to the size of the array - 1. make sure of no repeats and then store the numbers in a separate array so you might have:

"Bill"
"Bob"
"James"
"Chris"
"Thomas"

so you would generate numbers from 0 to 4 and might get:

3
1
4
0
2

in a separate array. Then copy across from the string array the string at the index specified by the second array. Then it becomes:

"Chris"
"Bob"
"Thomas"
"Bill"
"James"

Hope this helps :)

would you please send me a c++ code of this, if you have because i tried but i can't get the right answer. my e-mail address: <snipped>

i ll b glad.

brahle 0 Newbie Poster

I use Borland aswell (i like it personally) as for the compiler it is just the play button (labeled as run) and when you say you click on the icon and it dissapears right away, are you talking about the Borland program itself, or the program you are trying to run? if it is the program it is because the computer is executing the program then seeing that there is nothing else to do closes itself. if you #include <conio> you can use the getch(); command at the end of your program which will keep the window open until you press anykey then it will close.

I say djgpp is way better than Borland. Frist of all, djgpp is a Gnu software. Secondly, you can use much more memory than in Borland's compiler. In the end, in most of the competitions the djgpp is the default compiler.

BTW, why are you people using halfly C and halfly C++?
Why do you use cin and cout and normal pointers? You see, cin and cout are much slower than scanf() and printf(), and when you have to input/output more than 10k of data, you see the difference. That is why I use scanf() and printf(). Normal pointers aren't used much in C++ because there is a templated conatiner vector that you can use to easily manipulate arrays.

Elina:

#include <algorithm>
#include <cstdio>
#include <ctime>
#include <string>
#include <vector>
using namespace std;
const int NULA = 0;
vector< string > names;

template< typename _T > inline void shuffle( _T begining, _T ending ) {
  int size = ending - begining;
  for( _T it = begining; it < ending; ++it  )
    swap( *(it), *(begining + (int)rand % size ) );
}

int main( void ) {
  int n;
  char buff[256];
  srand( (unsigned)time( 0 ) );

  scanf( "%d", &n ); 
  names.reserve( n );
  for( int i = 0; i < n; ++i ) {
    scanf( "\n%[^\n]s", buff );
    names.push_back( buff );
  }
  shuffle( names.begin(), names.end() );
  for( int i = 0; i < n; ++i ) 
    printf( "%s\n", names[i].c_str() );

  return NULA;
}
venomlash 55 Junior Poster

Quote:
"...my computer says it doesn't have i0stream and several other headers..."

Did you maybe put in i0stream like you did in your message? Stupid question, but it only takes iostream.

uu666 0 Newbie Poster

i found something these days that looks like this:

#include <iostream.h> //for cout
#include <conio.h> //for clrscr() and getch()
#include <stdlib.h> //for randomize() and rand()

void main()
{
clrscr();

randomize();
cout << rand() << endl;

getch();
}

hope it helps :)

evilsilver 0 Junior Poster in Training

BTW, why are you people using halfly C and halfly C++?
Why do you use cin and cout and normal pointers? You see, cin and cout are much slower than scanf() and printf(), and when you have to input/output more than 10k of data, you see the difference. That is why I use scanf() and printf(). Normal pointers aren't used much in C++ because there is a templated conatiner vector that you can use to easily manipulate arrays.

i know that is a faster way of doing it but remember that not everyone is dealing with that much memory need and may only know about cout and cin which are simpler to use and are first thing that people learn about (hello world program always uses this, that i see anyways)

this way the code snipet can be used by new programmers and by those that may not know this code yet


just thought i would point that out lol

o and by the way i am using microsoft cisual studio 2005 now, works great and has a lot more functionality than borland, but borland was good to learn on from it's simplicity too lol kk well there wasn't much help in this post so i gonna shut up now lol

bmanoman 0 Newbie Poster

How would i create more than one random number, between 1, and 3, kind of like the slots [#],[#],[#] each filled with a random number...i tried using the examples here but they would just give me the same random numbers and would bring up the same numbers every time i ran it. if i got [3],[2],[3]. it would keep repeating those every time i ran it...id really appreciate the help

evilsilver 0 Junior Poster in Training

How would i create more than one random number, between 1, and 3, kind of like the slots [#],[#],[#] each filled with a random number...i tried using the examples here but they would just give me the same random numbers and would bring up the same numbers every time i ran it. if i got [3],[2],[3]. it would keep repeating those every time i ran it...id really appreciate the help

the problem with rand is that it isn't truely random, it is a psuedo random, or fake random. it has a list of numbers that it follows and though is alright for some very light things, is very predictable and will repeat it's self eventually.

if you read the rest of the snipet look for srand() it basically has the compiler pick a spot in the string of numbers it has for psuedo random so that it looks more random everytime you run the program

draclich 0 Newbie Poster
#include <iostream> 
#include <ctime> 
#include <cstdlib>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    int lowest=1, highest=10; 
    int range=(highest-lowest)+1; 
    for(int index=0; index<20; index++){ 
        random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
        cout << random_integer << endl; 
    } 
}

Greetings
I'm new to C++ and started playing with the above code. I edited the code a bit to allow for a wider range, and a smaller range, but no matter what range i specified my first number was always a 1 or a 2. Is there a way around that, or is it really random and the 20 some times I ran the code just kept giving me the same result out of bad luck? I'm using Microsoft Visual C++.

Thanks
-Drac

venomlash 55 Junior Poster

Like evilsilver said, rand isn't really random. It uses a really complex algorithm on the seed number (which you set with srand), so every time the program is run, it gives you the same output from the same algorithm with the same input. Try putting a srand([something]) inside the for loop and try again.

Xakil 0 Newbie Poster

Hi, im kinda new at C++ and this site and I wanted to see if someone could better explain about having a list of numbers (say 50) and then grabing them one by one randomly, but not reusing any of the 50 numbers that have already been used.

Thanks in advanced...

venomlash 55 Junior Poster

Create a

bool list[50]

, an array of 50 boolean (yes/no) values and set all of them to true at the start by using a for loop. Then, create the following function:

int randnum(int num){
    return rand()*num/(RAND_MAX+1);
}

Then, inside the body of your program, write the following:

int printnum;
for(int i=0; i<50; i++){
    printnum=randnum(50);
    if(list[printnum]==true){
        list[printnum]=false;
        cout<<printnum+1<<endl;
    } else {
        i--;
    }
}

If this doesn't work, tell me.
Venomlash

ahlongxp 0 Newbie Poster
#include <iostream> 
#include <ctime> 
#include <cstdlib>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    int lowest=1, highest=10; 
    int range=(highest-lowest)+1; 
    for(int index=0; index<20; index++){ 
        random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
        cout << random_integer << endl; 
    } 
}
int(range*rand()/(RAND_MAX + 1.0));

always return 0 on g++ (GCC) 4.1.2.
changed into

int((double)range*rand()/(double)(RAND_MAX + 1.0)) ;

fixed this problem.

Arctic wolf 5 Light Poster

Hello everybody,
I wanted to ask Bob about this piece of code:

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    int lowest=1, highest=10; 
    int range=(highest-lowest)+1; 
    for(int index=0; index<20; index++){ 
        random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
        cout << random_integer << endl; 
    }

you said that this formula:

random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0))

is better than using modulu because it solves some kind of compiler problems,I wanted to ask what kind of problems does it solve(why is it so different from the one that uses modulu)
and I also wanted to ask how did you develope this formula(what concept is it based on)?

Thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.