Hacker News new | past | comments | ask | show | jobs | submit login

In TXR Lisp, the algorithm I put in place basically finds the tightest power-of-two bounding box for the modulus, clisp the pseudo-andom number to that power-of-two range, and then rejects values outside of the modulus.

Example: suppose we wanted values in the range 0 to 11. The tightest power of two is 16, so we generate 4 bit pseudo-random numbers in the 0 to 15 range. If we get a value in the 12 to 15 range, we throw it away and choose another one.

The clipping to the power-of-two bounding box ensures that we reject at most 50% of the raw values.

I don't bother optimizing for small cases. That is, under this 4 bit example, each generated value that is trimmed to 4 bits will be the full output of the PRNG, a 32 bit value. The approach pays off for bignums; the PRNG is called enough times to cover the bits, clipped to the power-of-two box, then subject to the rejection test.




This is referred to as “Bitmask” in the article.


Off the top of my head, for a randomly chosen range of size n, you reject a throw with probability 1/4, right?


It's unintuitive, but I believe the probability ends up being 1-ln(2) if you think of n as being uniformly random.


For any power of two m, then for any range size n (with m/2 < n <= m), the probability of rejection is (m-n)/m. If any n is equally probable, then the average rejection is equal to the rejection of the average n (= 3*m/4): (m/4)/m = 1/4. This is true for any power of two m. I stand my case!


Hm, yeah not sure what I was thinking. Maybe expected number of attempts?


n uniformly random from what distribution? Or are you taking a limit somewhere?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: