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):
#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)
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!!