lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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