RandomLua Library
Re: RandomLua Library
Yes, it's probably the Lua number type. Lua uses by default a double precision floatingpoint number and AGen seems to be using a Lua built with single precision floatingpoint numbers. 32bit integers loose precision because 32bit floats only have 22 bits for the significand.
Shallow indentations.

 Prole
 Posts: 2
 Joined: Tue Jan 03, 2012 6:02 am
Re: RandomLua Library
linuxman, thank you for this library!
We're using it in an upcoming project and it is really quite spiffy for our simple needs. It's the first PRNG implementation in pure Lua we found which doesn't require additional bitwise operation libraries.
We're using it in an upcoming project and it is really quite spiffy for our simple needs. It's the first PRNG implementation in pure Lua we found which doesn't require additional bitwise operation libraries.
Re: RandomLua Library
I'm trying to use these scripts in Lua 4.0. Here's my attempt of doing the translation. Lua 4 doesn't have a "setmetatable" function, so I made a guess at what to do in my case.
Anyway, the problem is that the script is outputting the same decimal value every time I run it. Is this because I am using the script improperly? What is the proper way of using the script? Thanks!!
Mike
Code: Select all
function lcg(s, r)
local temp = {}
function temp:random(a, b)
local y = mod(self.a * self.x + self.c, self.m)
self.x = y
if not a then
return y / 65536
elseif not b then
if a == 0 then
return y
else
return 1 + mod(y, a)
end
else
return a + mod(y, b  a + 1)
end
end
function temp:randomseed(s)
if not s then
s = seed()
end
self.x = mod(s, 2147483648)
end
if r then
from Numerical Recipes
if r == 'nr' then
temp.a = 1664525
temp.c = 1013904223
temp.m = 65536
from MVC
elseif r == 'mvc' then
temp.a = 214013
temp.c = 2531011
temp.m = 65536
end
from Ansi C
else
temp.a = 1103515245
temp.c = 12345
temp.m = 65536
end
temp:randomseed(s)
return temp
end
print("wutwut =" .. lcg(0):random())
print("wutwut =" .. lcg(0):random())
print("wutwut =" .. lcg(0):random())
Mike
Re: RandomLua Library
Actually, Lua does have a setmetatable function: http://www.lua.org/pil/13.html
GitHub  MLib  Math and shape intersections library  Walt  Animation library  Brady  Camera library with parallax scrolling  Vimlovedocs  Help files and syntax coloring for Vim
 slime
 Solid Snayke
 Posts: 2946
 Joined: Mon Aug 23, 2010 6:45 am
 Location: Nova Scotia, Canada
 Contact:
Re: RandomLua Library
metatables got added in Lua 5.0. I'm not sure why anyone would use Lua 4.0 though... Lua 5.0 was released a decade ago. Lua 5.1 seven years ago, and Lua 5.2 two years ago (and unfortunately the online version of PiL is still the first edition, for Lua 5.0.)davisdude wrote:Actually, Lua does have a setmetatable function: http://www.lua.org/pil/13.html
Last edited by slime on Tue Sep 10, 2013 7:06 pm, edited 1 time in total.
Re: RandomLua Library
I'm working on a game called Homeworld 2 which was released in 2003 and uses Lua 4.0.
I had another person test my script and it worked OK in Lua 4.0.1, so I am SOL I guess unless someone has a better suggestion...
I had another person test my script and it worked OK in Lua 4.0.1, so I am SOL I guess unless someone has a better suggestion...
Re: RandomLua Library
It is not surprising that your script prints the same line three times. You create a new generator every time with the same seed and that will obviously return the same number. Save the table and call random on that a few times.
If you're already aware of that, you might want to check if Homeworld 2 was compiled with a Lua that uses singleprecision floatingpoint numbers. If so, calculations that go over 2^24 will not get the results you want. Here's a function that tests for some formats.
Edit: Looking at it again, Lua 4.0 does not provide an easy way to change it to single precision. Unless they modified it, it's probably double precision.
Code: Select all
local gen = lcg(0)
print("wutwut =" .. gen:random())
print("wutwut =" .. gen:random())
print("wutwut =" .. gen:random())
Code: Select all
function TestLuaNumberFormat()
local dbl = 2 ^ 53
local flt = 2 ^ 24
local int32 = 1073741823 * 2 + 1
local uint32 = 1073741823 * 4 + 3
local int64 = (1073741823 * 131072 + 131071) * 65536 + 65535
local uint64 = (1073741823 * 131072 + 131071) * 131072 + 131071
local fmt
if dbl ~= dbl  1 and dbl == dbl + 1 then
fmt = "doubleprecision floatingpoint number"
elseif flt ~= flt  1 and flt == flt + 1 then
fmt = "singleprecision floatingpoint number"
elseif int32 > 0 and int32 + 1 < 0 then
fmt = "signed 32bit integer"
elseif uint32 > 0 and uint32 + 1 == 0 and uint32 + 2 == 1 then
fmt = "unsigned 32bit integer"
elseif int64 > 0 and int64 + 1 < 0 then
fmt = "signed 64bit integer"
elseif uint64 > 0 and uint64 + 1 == 0 and uint64 + 2 == 1 then
fmt = "unsigned 64bit integer"
end
if fmt then
print("Feels like " .. fmt .. ".")
else
print("Unkown format.")
end
end
Shallow indentations.
Re: RandomLua Library
I ran TestLuaNumberFormat() and got "Feels like singleprecision floatingpoint number".
Re: RandomLua Library
Didn't expect that. You can rewrite it a bit to get the same results with single precision.
No guarantees on the statistical properties!
Code: Select all
function mul16(a, b)
local a_lo, b_lo = mod(a, 2^8), mod(b, 2^8)
local a_hi, b_hi = a  a_lo, b  b_lo
return mod(a_lo * b_lo + mod(a_lo * b_hi, 2^16) + mod(a_hi * b_lo, 2^16) + mod(a_hi * b_hi, 2^16), 2^16)
end
function lcg(s, r)
local temp = {}
function temp:random(a, b)
local y = mod(mul16(self.a, self.x) + self.c, self.m)
self.x = y
if not a then
return y / 65536
elseif not b then
if a == 0 then
return y
else
return 1 + mod(y, a)
end
else
return a + mod(y, b  a + 1)
end
end
function temp:randomseed(s)
if not s then
s = seed()
end
self.x = mod(s, 2147483648)
end
 'Numerical Recipes' parameters
temp.a = 26125
temp.c = 62303
temp.m = 65536
temp:randomseed(s)
return temp
end
Shallow indentations.
Re: RandomLua Library
This one works! No duplicate values after 10000 iterations.
I just need to figure out how to rewrite all my scripts. Currently I just pass the seeds to whatever functions need them. For instance,
I just need to figure out how to rewrite all my scripts. Currently I just pass the seeds to whatever functions need them. For instance,
Code: Select all
local my_seed_1 = {977322}
function srandom(seedobj, fVal1, fVal2)
seedobj[1] = mod(seedobj[1] * 1103515245 + 12345, 4294967296)
local temp_rand = seedobj[1] / (4294967296  1)
if (fVal2) then
return floor(fVal1 + 0.5 + temp_rand * (fVal2  fVal1))
elseif (fVal1) then
return floor(temp_rand * fVal1) + 1
else
return temp_rand
end
end
print(srandom(my_seed_1))
Who is online
Users browsing this forum: pirogronian and 9 guests