I have been trying to understand how using modulus can be dangerous and can introduce nasty but into the software.
Here is an illustration:
https://gist.github.com/anon7238593-create/5719c2ac8824650abbac4592ceee9408
in the notebook we can see that we used modulus to generate another random variable range which seems correct. you try to generate few number and they looks random but are they? no. here for sake of simplicity I have choose random range of 0-255 which I then convert to 0-100 range. here the probability that 0 comes is greater than having 100 because 101 doesn't evenly divide 255. there is a remainder of 53. which means the first 53 numbers are more likely to be chosen than the rest of the numbers which we can see in the graph.
you might be wondering why? it's rather simple. there are exactly 3 numbers in 0-255 that maps to number let's say 3 ( or any number less than or equal to 53 ). while there are only 2 numbers that maps to any number greater than 53. this affects their likeliness of being chosen.
which case this is fine?
only and only when the number of elements in bigger range is evenly divisible by the number of elements in smaller range.
eg, ~~0-2 ( 3 elements ) 255 % 3 = 0~~ 0-4 ( 4 elements ) 256 % 4 = 0
in this case the likeliness of an element being chosen doesn't change.
hope this was useful :)
Edit:
off by one correction. thanks to @eleijeep@piefed.social
The probability of going for
prepeats without hitting the lower end of the range is((N - M) / N) ^ pwhereNis the size of the input range andMis the size of the largest integer multiple of the output range, which falls exponentially towards zero aspincreases, so the chance of the process not terminating is zero.With OP's example, with an input range of 256 and an output range of 202, this would mean the probability of making 10 unsuccessful attempts would be
(54/256) ^ 10 = 0.00000017or about 1 in 6 million. The probability of making 20 unsuccessful attempts would be 1 in 36 trillion, and so on.