RandomLua Library
Re: RandomLua Library
Yes, it's probably the Lua number type. Lua uses by default a double precision floating-point number and AGen seems to be using a Lua built with single precision floating-point numbers. 32-bit integers loose precision because 32-bit floats only have 22 bits for the significand.
Shallow indentations.
-
- Prole
- Posts: 2
- Joined: Tue Jan 03, 2012 6:02 am
Re: RandomLua Library
linux-man, 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 | Vim-love-docs - Help files and syntax coloring for Vim
- slime
- Solid Snayke
- Posts: 3163
- 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 single-precision floating-point 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 = "double-precision floating-point number"
elseif flt ~= flt - 1 and flt == flt + 1 then
fmt = "single-precision floating-point number"
elseif int32 > 0 and int32 + 1 < 0 then
fmt = "signed 32-bit integer"
elseif uint32 > 0 and uint32 + 1 == 0 and uint32 + 2 == 1 then
fmt = "unsigned 32-bit integer"
elseif int64 > 0 and int64 + 1 < 0 then
fmt = "signed 64-bit integer"
elseif uint64 > 0 and uint64 + 1 == 0 and uint64 + 2 == 1 then
fmt = "unsigned 64-bit 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 single-precision floating-point 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: No registered users and 2 guests