Created
March 21, 2016 04:59
-
-
Save anonymous/9030f9045ef8c3e52dff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[------------------------------------ | |
RandomLua v0.3.1 | |
Pure Lua Pseudo-Random Numbers Generator | |
Under the MIT license. | |
copyright(c) 2011 linux-man | |
--]]------------------------------------ | |
local math_floor = math.floor | |
local function normalize(n) --keep numbers at (positive) 32 bits | |
return n % 0x80000000 | |
end | |
local function bit_and(a, b) | |
local r = 0 | |
local m = 0 | |
for m = 0, 31 do | |
if (a % 2 == 1) and (b % 2 == 1) then r = r + 2^m end | |
if a % 2 ~= 0 then a = a - 1 end | |
if b % 2 ~= 0 then b = b - 1 end | |
a = a / 2 b = b / 2 | |
end | |
return normalize(r) | |
end | |
local function bit_or(a, b) | |
local r = 0 | |
local m = 0 | |
for m = 0, 31 do | |
if (a % 2 == 1) or (b % 2 == 1) then r = r + 2^m end | |
if a % 2 ~= 0 then a = a - 1 end | |
if b % 2 ~= 0 then b = b - 1 end | |
a = a / 2 b = b / 2 | |
end | |
return normalize(r) | |
end | |
local function bit_xor(a, b) | |
local r = 0 | |
local m = 0 | |
for m = 0, 31 do | |
if a % 2 ~= b % 2 then r = r + 2^m end | |
if a % 2 ~= 0 then a = a - 1 end | |
if b % 2 ~= 0 then b = b - 1 end | |
a = a / 2 b = b / 2 | |
end | |
return normalize(r) | |
end | |
local function seed() | |
--return normalize(tonumber(tostring(os.time()):reverse())) | |
return normalize(os.time()) | |
end | |
--Mersenne twister | |
mersenne_twister = {} | |
mersenne_twister.__index = mersenne_twister | |
function mersenne_twister:randomseed(s) | |
if not s then s = seed() end | |
self.mt[0] = normalize(s) | |
for i = 1, 623 do | |
self.mt[i] = normalize(0x6c078965 * bit_xor(self.mt[i-1], math_floor(self.mt[i-1] / 0x40000000)) + i) | |
end | |
end | |
function mersenne_twister:random(a, b) | |
local y | |
if self.index == 0 then | |
for i = 0, 623 do | |
--y = bit_or(math_floor(self.mt[i] / 0x80000000) * 0x80000000, self.mt[(i + 1) % 624] % 0x80000000) | |
y = self.mt[(i + 1) % 624] % 0x80000000 | |
self.mt[i] = bit_xor(self.mt[(i + 397) % 624], math_floor(y / 2)) | |
if y % 2 ~= 0 then self.mt[i] = bit_xor(self.mt[i], 0x9908b0df) end | |
end | |
end | |
y = self.mt[self.index] | |
y = bit_xor(y, math_floor(y / 0x800)) | |
y = bit_xor(y, bit_and(normalize(y * 0x80), 0x9d2c5680)) | |
y = bit_xor(y, bit_and(normalize(y * 0x8000), 0xefc60000)) | |
y = bit_xor(y, math_floor(y / 0x40000)) | |
self.index = (self.index + 1) % 624 | |
if not a then return y / 0x80000000 | |
elseif not b then | |
if a == 0 then return y | |
else return 1 + (y % a) | |
end | |
else | |
return a + (y % (b - a + 1)) | |
end | |
end | |
function twister(s) | |
local temp = {} | |
setmetatable(temp, mersenne_twister) | |
temp.mt = {} | |
temp.index = 0 | |
temp:randomseed(s) | |
return temp | |
end | |
--Linear Congruential Generator | |
linear_congruential_generator = {} | |
linear_congruential_generator.__index = linear_congruential_generator | |
function linear_congruential_generator:random(a, b) | |
local y = (self.a * self.x + self.c) % self.m | |
self.x = y | |
if not a then return y / 0x10000 | |
elseif not b then | |
if a == 0 then return y | |
else return 1 + (y % a) end | |
else | |
return a + (y % (b - a + 1)) | |
end | |
end | |
function linear_congruential_generator:randomseed(s) | |
if not s then s = seed() end | |
self.x = normalize(s) | |
end | |
function lcg(s, r) | |
local temp = {} | |
setmetatable(temp, linear_congruential_generator) | |
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C | |
if r then | |
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes. | |
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC | |
end | |
temp:randomseed(s) | |
return temp | |
end | |
-- Multiply-with-carry | |
multiply_with_carry = {} | |
multiply_with_carry.__index = multiply_with_carry | |
function multiply_with_carry:random(a, b) | |
local m = self.m | |
local t = self.a * self.x + self.c | |
local y = t % m | |
self.x = y | |
self.c = math_floor(t / m) | |
if not a then return y / 0x10000 | |
elseif not b then | |
if a == 0 then return y | |
else return 1 + (y % a) end | |
else | |
return a + (y % (b - a + 1)) | |
end | |
end | |
function multiply_with_carry:randomseed(s) | |
if not s then s = seed() end | |
self.c = self.ic | |
self.x = normalize(s) | |
end | |
function mwc(s, r) | |
local temp = {} | |
setmetatable(temp, multiply_with_carry) | |
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C | |
if r then | |
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes. | |
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC | |
end | |
temp.ic = temp.c | |
temp:randomseed(s) | |
return temp | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment