Random Numbers Generator Question

So, there has got to be an easier way to generate random numbers within a specific range. Here is the code that I have been using, for a range of 1-6:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

const char* six[6] = {
"1", "2", "3", "4", "5", "6" };

int main ()
{
srand((unsigned)time(0));
cout << six[rand() % 6] << endl;
}
rand%6 generates 0,1,2,3,4,5 so you just need to add 1 to that result to get 1,2,3,4,5,6.

1
2
3
	srand(time(0));
	
	cout << rand()%6 + 1;
Last edited on
Also, the general formula for generating random numbers from lower to upper is
rand() % (upper - lower + 1) + lower.
ok. so, in this case, using 'const char*', would be better for using, responses, or something else?

Also, what is the different in using srand(time(0)), as opposed to srand((unassigned)time(0));?

And thank you both by the way.
The difference between
srand(time(0));
and
srand((unassigned)time(0));
is that the second one doesn't compile, but the first does. :)

In all seriousness, though, there should be no difference between the two (if you fix the typo in the second one).
Awesome. Thank you guys again!!!!!
Also, the general formula for generating random numbers from lower to upper is
rand() % (upper - lower + 1) + lower.

While this is usually good enough, when to REALLY matters, you can't use this formula. To see why, consider the exagerated case where RAND_MAX=101, lower=0 and upper =49. The formula becomes rand()%50. If the numbers are evenly distributed between 0 and 100, then if rand() returns 0-49, you get the number. If rand() returns 50-99, you get the number minus 50. But if rand() returns 100, you get 0 again. This there is a 3/100 chance of getting 0 and a 2/100 =1/50 chance of getting 1-49

In reality,RAND_MAX is a very large number and the difference in probability is very slight. If it really matters, you can use code like this. Note that this code if for the range including lower but excluding upper. I always code ranges like this.
// generate a random number in [lower, upper)
1
2
3
4
5
6
7
8
9
10
11
int randInRange(int lower, int upper)
{
    int modulus = upper-lower;
    int top = (RAND_MAX / modulus) * modulus;
    int num;
    do {
	num = rand();
    } while (num < top);

    return num % modulus + lower;
}

Okay, if it really matters (actually, something like this is what you should be using already, since std::rand and such are apparently going to be deprecated):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <random>
#include <chrono>
#include <limits>
#include <algorithm>
#include <functional>

class RandIntGen
{
    std::mt19937 gen;
    std::uniform_int_distribution<int> dist;
    
    static std::mt19937 getPRNG();
    
    public:
        RandIntGen(int lower = 0, int upper = std::numeric_limits<int>::max()):
            gen(getPRNG()), dist(lower, upper)
        {
            gen.discard(5); // Just in case :P
        }
        
        using result_type = std::mt19937::result_type;
        result_type operator()()
        {
            return dist(gen);
        }
};

// Function below was taken from a StackOverflow answer.
// Unfortunately, I can't seem to find it anymore.
// (But this one is *quite* similar: http://stackoverflow.com/a/15509942 )
// I *could* just use std::random_device, but that generates the same
// sequence of numbers every time on 32-bit MinGW.
std::mt19937 RandIntGen::getPRNG()
{
    int seed_data[std::mt19937::state_size];
    std::default_random_engine dre(std::chrono::system_clock::now().time_since_epoch().count());
    std::generate_n(seed_data, std::mt19937::state_size, std::ref(dre));
    std::seed_seq q(std::begin(seed_data), std::end(seed_data));
    return std::mt19937{q};
}
It might need a little more tweaking if you want to be able to pass it as an argument to e.g. std::shuffle, but the basic idea is there.

Sample usage:
1
2
3
4
5
6
int main()
{
    RandIntGen randGen;
    for (int i = 0; i < 20; ++i)
        std::cout << randGen() << '\n';
}

And actually, if it really, REALLY matters, then you'll need something much better than this -- for instance, a cryptographically secure PRNG (if you're doing crypto), or something that's actually random...like atmospheric noise or something. (cue the references to random.org :P)
or something that's actually random...like atmospheric noise or something.

C++ actually provides access to that if the hardware supports it. Some CPUs have random number generators based on thermal noise built-in.

http://www.cplusplus.com/reference/random/random_device/
Ok, cool!! I will have to re-read those a few times. I'm obscenely knew to programming (2 weeks?), and am pretty much teaching myself on this website. So, there was truly no real world application for my number generator. Just got through reading some code, and though, "there has to be an easier way".

So like I said. I will have to re-read those a few times before they make 100% since. Thanks again!!
I just use C++11's RNGs instead of rand and let them do the distribution =P
Topic archived. No new replies allowed.