[Lua] rand.lua - an alternative to the not so random math.random() in-built function 08-02-2013, 10:26 PM
#1
I often happened to find troubles in the randomness of math.random(). After some researches I found out it's a pretty common issue.
http://stackoverflow.com/questions/46197...rms-in-lua
You could as well google "lua math.random not random" or whatever and look at the results.
This is why I just coded a pseudo-random number generator function.
To call it you can add the code in your script or save it as rand.lua and then use:
require() should work better. Call the function:
This is still buggy, I'll definitely work on this, will get this better. Sometimes, when you use the function twice in a very short time, you might get two some similar numbers, because of the binding to os.clock()/os.time(). There are a few chances that the function will die and show an error message, I reduced a lot the times it should occur.
Please, let me know about how the statistics go for you; if you quickly call the function many times, how many and in how short times does the function return fairly similar numbers? How many times do you get errors? How about performance? Maybe a comparation to math.random()?
http://stackoverflow.com/questions/46197...rms-in-lua
You could as well google "lua math.random not random" or whatever and look at the results.
This is why I just coded a pseudo-random number generator function.
Code:
function rand(floor,ceil)
-- rand.lua
--
-- pseudo-random number generator (PRNG) version 0.1 (beta)
-- an alternative to the mostly sloppy math.random()
--
-- you are allowed to use, edit or redistribute this code in whole or part as long as you give credits
--
-- lua 5.1
-- authored by noize
assert(tonumber(floor) == floor,"error: floor needs to be a number.")
assert(tonumber(ceil) == ceil,"error: ceil needs to be a number.")
-- instead of using the type() function I use this method as it lets nil values pass as well
local n = {}
math.randomseed(os.time())
n.r = math.random(65535) / (os.time() + os.clock())
n.x = n.r * os.time() * os.clock()
if os.time() >= 1200000000 then
n.a = n.x * math.sqrt(n.r) / os.clock() * os.time()
else
n.a = (n.x / 2) * n.r ^ 3 / os.clock() * os.time()
end
n.j = math.random(math.random(),math.sqrt(math.random()) + math.random() * os.clock())
n.k = math.random(math.random(),math.random() / math.random() * os.time())
if math.random() > 0.54 then
if math.random() > 0.78 then
n.a = n.a * math.random(
n.j,
n.j + math.random(math.random(1,2),math.sqrt(math.random())+math.random()*os.clock()/math.random())
)
else
n.a = n.a * math.random(
math.sqrt(math.random(
math.random(),
math.sqrt(
math.random() + math.random() + os.clock() ^ (math.random() + math.random() + math.random()) / (math.random() + math.random()) + math.random()
) * math.random()
)) * math.sqrt(math.random()),
math.sqrt(math.random()) + math.sqrt(n.j) + math.random(
math.random(1,2),
math.sqrt(n.j) / math.random() + ((math.random() + math.random()) / (math.random() + math.random() + math.random() + math.random()))
) / math.sqrt(math.random())
)
end
else
if math.random() > 0.78 then
n.a = n.a * math.random(
n.k,
n.k + math.random(math.random(1,2),math.sqrt(math.random())+math.random()*os.time()/os.clock()/math.random())
)
else
n.a = n.a * math.random(
math.sqrt(
(n.k - (math.random() * n.k)) + math.sqrt(n.k) + math.random(
math.random(0,1),
math.sqrt(
n.k + (math.random() + math.random() + math.random() + math.random()) / ((math.random() + math.random()) * os.time() ^ ((math.random() + math.random() + math.random()) / (math.random() + math.random())))
)
)
),
tonumber(
math.random() + n.k + math.random(
math.random(1,2),
math.sqrt(
math.random(1,2) + math.random() + os.clock() ^ (math.random() + math.random() + math.random() + math.random()) / math.sqrt(math.random() + math.random() + math.random() * 3)
) / math.sqrt(math.random())
)
)
)
end
end
if n.a == 0 then
n.a = math.random()
end
n.a = n.a * math.sqrt(math.random(1,10))
if floor == nil and ceil == nil then
return n.a
elseif floor == nil then
while n.a > ceil do
math.randomseed(os.time() * os.clock() ^ os.time())
n.a = n.a / math.sqrt(os.clock() - math.sqrt(os.clock() - math.random()))
end
return n.a
elseif ceil == nil then
while n.a < floor do
math.randomseed(os.time() * os.clock() ^ os.time())
n.a = n.a * math.sqrt(os.clock() - math.sqrt(os.clock() - math.random()))
end
return n.a
else
assert(floor < ceil,"error: floor needs to be lower than ceil.")
while n.a > ceil or n.a < floor do
if n.a > ceil then
math.randomseed(os.time() * os.clock() ^ os.time())
n.a = n.a / math.sqrt(math.sqrt(os.clock()))
end
if n.a < floor then
math.randomseed(os.time() * os.clock() ^ os.time())
n.a = n.a * math.sqrt(math.sqrt(math.random()))
end
end
return n.a
end
endTo call it you can add the code in your script or save it as rand.lua and then use:
Code:
require("rand")
-- or as well
dofile("rand.lua")require() should work better. Call the function:
Code:
rand(1,10) -- this will return a pseudo-random number between 1 and 10
math.floor(-rand(100,1000)) -- this will return a pseudo-random integer between -1000 and -100
print(rand(nil,99)) -- this will output a pseudo-random number between 0 and 99
print(math.ceil(rand(3,nil))) -- this will output a pseudo-random integer betwen 3 and, theorically any number (practically, you will see there is a limit)
rand(nil,nil) -- this is in theory the most random possibility with rand()This is still buggy, I'll definitely work on this, will get this better. Sometimes, when you use the function twice in a very short time, you might get two some similar numbers, because of the binding to os.clock()/os.time(). There are a few chances that the function will die and show an error message, I reduced a lot the times it should occur.
Please, let me know about how the statistics go for you; if you quickly call the function many times, how many and in how short times does the function return fairly similar numbers? How many times do you get errors? How about performance? Maybe a comparation to math.random()?
My Bitcoin address: 1AtxVsSSG2Z8JfjNy9KNFDUN6haeKr7LiP
Give me money by visiting www.google.com here: http://coin-ads.com/6Ol83U
If you want a Bitcoin URL shortener/advertiser, please, use this referral: http://coin-ads.com/register.php?refid=noize
Give me money by visiting www.google.com here: http://coin-ads.com/6Ol83U
If you want a Bitcoin URL shortener/advertiser, please, use this referral: http://coin-ads.com/register.php?refid=noize


![[+]](https://sinister.li/images/modern/collapse_collapsed.png)


![[Image: 2YpkRjy.png]](http://i.imgur.com/2YpkRjy.png)