That Wiki page makes it sound very complicated but for this purpose our implementation can be laughably simple which has the advantage that you know why it works and can maintain it properly with confidence.
Get suitably large inputs, for example if you're trying to pick integers between 2 and 11 inclusive, a nibble (half a byte) would be fine. Now, is the random input in the range you wanted? If so, you've got your answer. If not, throw this random input away and get more.
Too many programmers act as though random numbers were a precious resource.
The thing you actually want is rejection sampling: https://en.wikipedia.org/wiki/Rejection_sampling.
That Wiki page makes it sound very complicated but for this purpose our implementation can be laughably simple which has the advantage that you know why it works and can maintain it properly with confidence.
Get suitably large inputs, for example if you're trying to pick integers between 2 and 11 inclusive, a nibble (half a byte) would be fine. Now, is the random input in the range you wanted? If so, you've got your answer. If not, throw this random input away and get more.
Too many programmers act as though random numbers were a precious resource.
I got lost when OP talked about using 10 integers to choose from 3 choices. I think I figured out what was missing in the explanation.
random_u64() Mod 3 does indeed have a single bucket that is oversized. This overweights one option by about 5×10^-20.
rand() Itself has only 32767 possible values, so it's also common for a bucket to be overweighted depending on the number of buckets.
Makes you wonder at what point overweighting by about 5×10^-20 is something you'd want to care about.