On Friday, 20 December 2013 at 16:20:44 UTC, marcpmichel wrote:
On Friday, 20 December 2013 at 15:05:07 UTC, bearophile wrote:

Here is the ugly thing :

And wrong:

if (rand.front() % 9 == 7) {


Do you mean I should have used :
if (uniform(0,10) == 7) {
instead ?

TL;DR version:
Actually, the equivalent would be uniform(0, 9), but yes, that'd be the preferable approach there. (also note https://github.com/jbrains/trivia/blob/7b473f9fbbd125b0ab1c2e82582b8a8c414ca501/d/source/trivia.d#L19 too should be changed to `uniform(1, 6)` which will give numbers in the range [1 .. 6) ... that's what you want, right?)

Long version:
For more information, I've written a document on an implementation of uniform (which should be coming in 2.065, btw) which discusses the issue with just using the modulus operator:

Generally speaking, this new uniform will be _extremely_ close to the same speed of just using the modulus operator, but avoids the bias issue. I think there is no real good reason to not use the standard function anymore.

That said, the bias with such a small number (9) won't be significant. If rand gives you a uniform 32-bit number, then the distribution of rand % 9 will be [477218589, 477218589, 477218589, 477218589, 477218588, 477218588, 477218588, 477218588, 477218588] (notice how the first 4 have 1 more occurrence than the rest?)... so the bias is miniscule in this case.

The bias issue matters a lot more with larger numbers where some numbers could actually occur twice as often as others, or if your application demands high quality random numbers (think gambling games). Related to those reasons, even if your code doesn't use large numbers and isn't used for a gambling game now, it's still possible for it to eventually be used for such things (or to influence others to follow your example for the bad situations). For those reasons alone, it's pretty important to get in the habit of using the standard function.

But that's not all since the standard function is probably easier to read, too. Let's say you want to emulate a standard 6-sided die. If you want numbers in the range [1..6] (note inclusive bounds) it's easier to see immediately when you say `uniform!"[]"(1, 6)' rather than `rand % 6 + 1`

That's probably all TMI, but maybe all of that will be useful for you.

Reply via email to