简体   繁体   中英

C++ random number generation

For example, the following expression:

r = (rand() % 10)+1;

Generates a random number from 1-10 .

How can we make it generate random numbers from 0-10 ?

Thanks.

You're almost there! The rand() function returns a random value in a pretty large range (0 to RAND_MAX ). The use of the modulus operator wraps this down into a smaller range (from 0 to 9, since you're modding by 10) and then the +1 moves this to be from 1 to 10.

To get values between 0 and 10, you can take rand and mod its value by 11:

r = rand() % 11;

More generally, to get random values in the range [0, n], you can write

r = rand() % (n + 1);

And finally, to get values in the range [k, n + k], you can write

r = rand() % (n + 1) + k;

Of course, as purists will point out, this isn't necessarily going to give you truly uniform values because modding rand() by some value will not distribute all the integers evenly. This usually isn't a problem (you'll be off by a very, very small amount), but if it is you may want to consider looking into a more robust random number generator than rand() .

You leave out the +1 to start with 0. And since there are 11 different values you want, you need to calculate the remainder modulo 11 instead of 10.

r = rand() % 11;

Note that you need to seed a PRNG so it doesn't always produce the same sequence.

And the standard rand() function sucks. The quality of random numbers is very low, and not fit for many purposes. I strongly recommend using a better generator.

A Mersenne twister is a popular choice, and in one my projects I used Well512 since it's fast, good and easy to implement.

If the user must not predict the random numbers even those good PRNGs are not enough and you have to choose a cryptographic PRNG. They can neither be predicted (with realistic computational power) nor be distinguished from real random numbers unless you know the seed. They are a bit slower though.

Generating a uniform distribution is much simpler and less error prone in C++11 using std::uniform_real_distribution or for the integer case std::uniform_int_distribution . Here is a sample using std::uniform_real_distribution which displays a simple graphic to give a rough demonstration that it is uniform:

#include <iostream>
#include <iomanip>
#include <string>
#include <random>

int main()
{
    std::random_device rd;

    //
    // Engines 
    //
    std::mt19937 e2(rd());
    //std::knuth_b e2(rd());
    //std::default_random_engine e2(rd()) ;

    std::uniform_real_distribution<> dist(0, 10);

    const int nstars=95;     // maximum number of stars to distribute
    const int nintervals=10; // number of intervals

    int p[nintervals]={};

    for (int i=0; i<100000; ++i)
    {
      double number = dist(e2);
      ++p[int(number)];
    }

    std::cout << std::fixed; std::cout.precision(1);

    for (int i=0; i<nintervals; ++i)
    {
      std::cout << float(i) << "-" << std::setw(4) << float(i+1) << ": ";
      std::cout << std::string(p[i]*nstars/100000,'*') << std::endl;
    }

    return 0 ;
}

Sample result:

0.0- 1.0: *********
1.0- 2.0: *********
2.0- 3.0: *********
3.0- 4.0: *********
4.0- 5.0: *********
5.0- 6.0: *********
6.0- 7.0: *********
7.0- 8.0: *********
8.0- 9.0: *********
9.0-10.0: *********

Some of the sample code was taken from this reference .

This is a basic way to generate random numbers. The line of code that uses static_cast seeds the random number generator based on the current time, which means you get more numbers besides between 0 and 10 instead of just one.

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

using namespace std;

int main()
{
    srand(static_cast<unsigned int>(time(0))); // Seed random number generator
    unsigned int r = rand() % 10; // Generate random number
}

Here is simpler way of generating random numbers with modern C++.

#include <iostream>
#include <random>

int main()
{
    std::random_device device;
    std::default_random_engine engine(device());
    std::uniform_int_distribution<int> r(0, 10);
    std::cout << r(engine) << std::endl;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM