# Thread: Modulus and Random number generation.

1. ## Modulus and Random number generation.

I am making a random number generator. I have fixed all issues except for one. I am supposed to ask the user for how many digits the user wants the numbers to have. How many numbers does the user want. Then randomly generate numbers according to what the user entered. So if the user said 2 digits and wanted 4 numbers then it would output 4 random numbers in the range of 10 to 99.

My notes from class show this working correctly. And it does work correctly. But I don't understand the math here or how the modulus effects it. I was able to get 1 and 2 digits to work but once I get to 5 it doesn't generate numbers correctly. it will only generate number s

Code:
```int min =1;
int max = 9;int number1 = rand();
cout << number1 % max + min << "\t";```
here is the 3 digit code I have. I also need to figure out how to make it unique so no number generates more then once. I think the issue may be that the numbers are not unique and it is generating the same number and that is somehow effecting the numbers it is outputting. It is either that or my math is wrong. If someone could explain to me how the modulus effects it I would probably be able to figure the others out.
Code:
```if (intLength == 5)
{
for (int i = 0; i<intQuantity; i++)
{
int min = 10000;
int max = 90000;
int number1 = rand();

if (intQuantity > max)
{
intQuantity = max;
}

cout << number1 % max + min << "\t";
}```

2. Okay so I think I misinterpreted the issue. It is not that the math isn't right. For some reason it is only generating the lower numbers.

3. But the math is incorrect. According to this web site, rand() can return anything from 0 to RAND_MAX, which is why you want to clamp the result down to anything from min to max. The size of the range matters when you use the % operator, not the max itself.

number1 = number1 % (max - min) + min;

You could also do:

Code:
```do
number1 = rand();
while (number1 < min || number1 > max);```
This requires no math, but you have to wait for rand to return a number that works. That's the only drawback.

4. Originally Posted by whiteflags
This requires no math, but you have to wait for rand to return a number that works. That's the only drawback.
And sometimes you have to wait forever because rand really doesn't know how to create uniform distributions. Plus, it's also deprecated.
I suggest you use the new random number generation facilities in C++ if your compiler supports C++11: std::uniform_int_distribution - cppreference.com

5. Originally Posted by Elysia
And sometimes you have to wait forever because rand really doesn't know how to create uniform distributions.
That's not quite accurate. Non-uniformity doesn't mean it's possible for some numbers to never occur, it simply implies that they may not occur quite as often as others.

What whiteflags posted is the wrong way to implement the rejection method. If you have a moment, it would be handy if you could review my recent draft article on generating evenly distributed random numbers, which also happens to explain how to do it properly:
Random Numbers

This site does point out some historical rand implementations really were crap, but I would imagine that anything less than 10 years old would typically be adequate for many purposes:
There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls).

rand() is not recommended for serious random-number generation needs, like cryptography. It is recommended to use C++11's random number generation facilities to replace rand().(since C++11)

6. Originally Posted by iMalc
That's not quite accurate. Non-uniformity doesn't mean it's possible for some numbers to never occur, it simply implies that they may not occur quite as often as others.
I did not literally mean forever. I meant, as you said, that for some numbers, the probability is really low. I have run into situations where I've pretty much run into an endless loop trying to rand some specific numbers.
The distribution is also really, really poor when I tested on Visual C++, so if that bothers you, then that's another reason not to use it.

7. Originally Posted by Elysia
I did not literally mean forever. I meant, as you said, that for some numbers, the probability is really low. I have run into situations where I've pretty much run into an endless loop trying to rand some specific numbers.
Right, but as noted, the above is not how to properly implement the rejection method. One fact within the article I wrote is that in the worst case there is always less than 50% chance of the rand() value being rejected, and it is typically far lower than that.

The distribution is also really, really poor when I tested on Visual C++, so if that bothers you, then that's another reason not to use it.
That's out of context to the point of being untrue.
One can write a program to perform statistical analysis on it's rand() output, and uncover some issues if you know what to look for, but generally these things are unnoticeable for common applications. Visual C++ implementations have always had a good period period of 2^32 (source) and consequently a perfectly even distribution in the long run. They can be faulted yes, but "really, really poor" is a gross exaggeration.

People who try to point out bias in the implementation of Visual Studio's rand implementation generally have actually introduced the bias themselves by using purely a modulus operation to reduce the output range.