Reputation: 3066
I want a templatized class that generates random numbers between a lower and upper limit (both limits can be negative). This is what I have so far:
template <typename T>
T RandomGenerator<T>::generate(T lowerLimit, T upperLimit)
{
static bool initialized = initialize();
return double(rand()) * (upperLimit - lowerLimit) / RAND_MAX + lowerLimit;
}
template <typename T>
bool RandomGenerator<T>::initialize()
{
srand(time(NULL));
}
int iVal = RandomGenerator<int>::generate(1, 10); //Generate integers between (and including) 1 and 10.
double dVal = RandomGenerator<double>::generate(-1, 1); //Generate doubles between (and including) -1 and 1.
This correctly generates double values, but the integers are off. Does anyone know how to code a universal solution for both ints and doubles? I don't want a different function for ints and doubles.
Upvotes: 0
Views: 1307
Reputation: 16612
When you generate a number 'between' 1 and 10, you actually generate a random double ranging from 1.0 to 10.0.
Then when converting that back to an integer, the number will be truncated. So 1.X becomes 1, 2.X becomes 2, etc. 10.X will become 10, but the only value generated in that range is exactly 10.0 - which will be rare as it only happens at the extreme limit of the underlying random function.
So for integers, your range calculation is not appropriate.
I would really suggest just specialising your template for integers.
Note that this is not really an issue of rounding - if you rounded to nearest, the top and bottom values would be half as likely as the others.
Also, please don't simply take the average to work out if your random generation is correct or not - this will hide many errors in the distribution. For example, if both upper and lower limits were wrong by the same amount, the average could still be correct (for example, tweaking the rounding could look correct when it is not). Or your numbers could be on a bell-curve or something, rather than flat. Calculate a histogram.
Upvotes: 1