[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?"

```

• Follow-Ups:
• References: