[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Unexpected randomseed results (was [ANN] uuid: pure Lua uuid generator)
- From: Sean Conner <sean@...>
- Date: Sat, 11 May 2013 04:15:18 -0400
It was thus said that the Great Thijs Schreijer once stated:
> But to make matters worse, the library currently creates the exact same
> sequence of uuids every time I start it.
>
> The seed used is `socket.gettime()*10000` which is far better than
> `os.time()` __unless you notice__ that math.randomseed [1] casts the
> number to an int. Which means that the former gets reduced to either 0 or
> 1 (on my system) and all randomness is completely gone. (I only found out
> by accident)
math.randomseed() calls the standard C library function srand(), which
actually takes an unsigned int (fixed [2] in Lua 5.2). Not much can be done
here, unless you use a non-standard random number generator.
> Truncation (2nd and 3rd column unequal) occurs already at a far lower
> number (2,147,483,648) than the socket-seed created (13,682,539,535,070)
> and from there on randomness is gone (same uuids are generated).
What you probably want is something like:
math.random((package.loaded['socket'].gettime()*100000) % (2^31-1))
to force the range into an integer [3].
> PS. Is there a way to detect the maximum int size used from Lua?
Short answer: no. Long answer: Mu. [4] Because stock Lua uses doubles
(unless changed) it can actually manipulate integer values up to 2^53, which
is larger than an int on 32-bit systems (and possibly on 64-bit systems
which use a 32-bit int).
In thinking about it, Lua should do the following:
srand(luaL_checkint(L,1) % INT_MAX);
(or in 5.2
srand(luaL_checkunsigned(L,1) % UINT_MAX);
)
But that's not up to me.
-spc (Random numbers are hard, let's launch rockets!)
[1] http://www.lua.org/source/5.1/lmathlib.c.html#math_randomseed
[2] For various values of "fixed". Lua 5.2 has luaL_checkunsigned(),
the problem you are having is still there---unexpected casting.
[3] You can probably get away with using (2^31-1) for math.random().
This is the typical signed integer maximum. You could also try
(2^32-1). This is the typical unsigned integer maximum.
[4] The answer to "Does a dog have the Buddha nature?"