|
Below is rand_upto(n) that work without patching any c code. It call math.random() instead of math.random(0, hi), avoiding bias. I made an error earlier. On my machine, RAND_MAX = 0x7fff local rand, floor = math.random, math.floor local RSIZE = 2 ^ 15 -- RAND_MAX + 1 function rand_upto(n) -- return random r, 0 <= r <= n local hi = RSIZE local lo, r = n % hi + 1, 0 if lo > 1 then while lo + lo < hi do hi = hi / 4 end -- reduce rand calls if lo >= hi then hi = hi * 2 end -- scaled too far repeat r = rand() * hi until r < lo -- remove bias end if lo > n then return floor(r) end return floor(r) + RSIZE * rand_upto((n - lo) / RSIZE) end |