lua-users home
lua-l archive

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


On Sat, Mar 3, 2018 at 1:37 PM, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
We are considering xorshift128+ for Lua 5.4, so that we can have 64 bits
of randomness.

 Good choice! I've been using it coded in Lua...

-- e_random.lua
-- for Lua 5.3
-- based on http://xoroshiro.di.unimi.it/

M = {} -- the module to be returned

-- http://xoroshiro.di.unimi.it/splitmix64.c

local function splitmix64_next (random_state)
    local x = random_state[1]
    x = x + 0x9E3779B97F4A7C15
    random_state[1] = x
    local z = x
    z = (z ~ (z >> 30)) * 0xBF58476D1CE4E5B9
    z = (z ~ (z >> 27)) * 0x94D049BB133111EB
    return z ~ (z >> 31)
end

local splitmix64_random_state = {0x5a5a5a5a5a5a5a5a5a5b, next = splitmix64_next}

-- http://xoroshiro.di.unimi.it/xorshift128plus.c

local function xorshift128plus_next (random_state)
    local s1 = random_state[1]
    local s0 = random_state[2]
    local res = s0 + s1
    random_state[1] = s0
    s1 = s1 ~ (s1 << 23)
    random_state[2] = s1 ~ s0 ~ (s1 >> 18) ~ (s0 >> 5)
    return res
end

-- 

local default_random_state = {splitmix64_next(splitmix64_random_state),
                              splitmix64_next(splitmix64_random_state),
                              next = xorshift128plus_next}

local function random64 (random_state)
    if type(random_state) ~= 'table' then random_state = default_random_state end
    return random_state.next(random_state)
end


-- [0.0, 1.0]
local function random_real_53 (random_state)
    local x = random64(random_state)
    return (x >> 11) * (2.0 ^ -53)
end

-- (0.0, 1.0]
local function random_real_53ish (random_state)
    local x = random64(random_state)
    return ((x >> 11) + 1) * (2.0 ^ -53)
end

-- [0.0, 1.0]
local function random_real_63 (random_state)
    local x = random64(random_state)
    return (x >>  1) * (2.0 ^ -63)
end

M.random64    = random64
M.random_real = random_real_63

return M

-- e