RandomLua Library

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: RandomLua Library

Post by Boolsheet »

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.
CarSoccerRobots
Prole
Posts: 2
Joined: Tue Jan 03, 2012 6:02 am

Re: RandomLua Library

Post by CarSoccerRobots »

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.
posfan12
Prole
Posts: 5
Joined: Mon Sep 09, 2013 9:26 pm

Re: RandomLua Library

Post by posfan12 »

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.

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())
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
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: RandomLua Library

Post by davisdude »

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
User avatar
slime
Solid Snayke
Posts: 2946
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: RandomLua Library

Post by slime »

davisdude wrote:Actually, Lua does have a setmetatable function: http://www.lua.org/pil/13.html
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.)
Last edited by slime on Tue Sep 10, 2013 7:06 pm, edited 1 time in total.
posfan12
Prole
Posts: 5
Joined: Mon Sep 09, 2013 9:26 pm

Re: RandomLua Library

Post by posfan12 »

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... :(
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: RandomLua Library

Post by Boolsheet »

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.

Code: Select all

local gen = lcg(0)
print("wutwut =" .. gen:random())
print("wutwut =" .. gen:random())
print("wutwut =" .. gen:random())
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.

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
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.
Shallow indentations.
posfan12
Prole
Posts: 5
Joined: Mon Sep 09, 2013 9:26 pm

Re: RandomLua Library

Post by posfan12 »

I ran TestLuaNumberFormat() and got "Feels like single-precision floating-point number".
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: RandomLua Library

Post by Boolsheet »

Didn't expect that. You can rewrite it a bit to get the same results with single precision.

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
No guarantees on the statistical properties! :P
Shallow indentations.
posfan12
Prole
Posts: 5
Joined: Mon Sep 09, 2013 9:26 pm

Re: RandomLua Library

Post by posfan12 »

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,

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))
Post Reply

Who is online

Users browsing this forum: pirogronian and 9 guests