In addition to @Edward's great analysis, I'd add this: name your variables appropriately! What are x
, m
, a
, c
, u
, and r
?
It looks like m
is the number of random numbers to generate. So why not name it numRands
or something like that? (Or if you prefer a different style, call it num_rands
.)
It looks like x
is some sort of state for the generator - initially the seed, then the current state after that. Perhaps naming it seed
or state
could help?
a
and c
seem to be a scale and add term, so perhaps they could be named scale
and offset
or something like that? (At the very least, a comment explaining how they work would be a good idea.)
u
is the random value converted to a float between -1 and 1, and is the final value you're trying to calculate. It could be called randomVal
or result
, or something like that.
And finally, r
appears to be which bin the numbers will end up in. Name it bin
.
Edit: As @DarrelHoffman points out, the name of the function could be greatly improved, too. I agree with his suggestion of countFrequency()
or something similar.
And while we're on the subject, this could be made more object-oriented, too. The state and method of calculation of the random number generator shouldn't really be known or accessible to other classes or code. That way, if you decide you want to change it to a better method in the future, you can keep the interface, but replace the inner workings and any code that calls it should just work.
You could make a RandGen
class that looks something like this:
class RandGen {
public:
RandGen(const long seed, const unsigned long maxNumRands) : state(seed), maxRands(maxNumRands) {}
float getNextRand();
private:
long state = -2;
unsigned long maxRands = 1000;
};
float RandGen::getNextRand()
{
const long scale = 33;
const long offset = 61;
state = (state * scale + offset) % maxRands;
return (float)state / (float)maxRands;
}
Then your frequency counting function could just call getNextRand()
, something like this:
void countFrequency(float frequencies[], const unsigned long numFrequencies,
const unsigned long numRands)
{
RandGen randGen(-2, numRands);
for (int i = 0; i < numRands; ++i)
{
int r = randGen.getNextRand() * 10.0;
frequencies [ r ] += 1;
}
}
It would be a good idea to separate out the printing of the frequencies, too:
void printFrequency(float frequencies[], const unsigned long numFrequencies)
{
for (int i = 0; i < numFrequencies; ++i)
{
const float rangeMin = (float)i / 10.0;
const float rangeMax = (float)(i + 1) / 10.0;
std::cout << "[" << rangeMin << ";" << rangeMax << "]"
<< " | " << frequencies [ i ] << "\n-----------------" << std::endl;
}
}
(And if you want to be really object-oriented, you would probably be better off using a std::vector
for frequencies[]
than passing around an array and a count, too.)