summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-17 16:00:24 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-17 16:00:24 -0300
commit4eefef07ab1c136f901d816822c79336fa89336d (patch)
treece2232ba8a09287899af1ac07af0c902800bfae6
parent9c28ed05c95cb6854d917ac3e3ed7be9ae109480 (diff)
downloadlua-4eefef07ab1c136f901d816822c79336fa89336d.tar.gz
lua-4eefef07ab1c136f901d816822c79336fa89336d.tar.bz2
lua-4eefef07ab1c136f901d816822c79336fa89336d.zip
'math.randomseed()' returns the seeds it used
A call to 'math.randomseed()' returns the two components of the seed it set, so that they can be used to set that same seed again.
-rw-r--r--lmathlib.c9
-rw-r--r--manual/manual.of3
-rw-r--r--testes/all.lua11
-rw-r--r--testes/math.lua11
4 files changed, 27 insertions, 7 deletions
diff --git a/lmathlib.c b/lmathlib.c
index f6f0b426..1d310b2d 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -605,20 +605,24 @@ static void setseed (Rand64 *state, lua_Unsigned n1, lua_Unsigned n2) {
605static void randseed (lua_State *L, RanState *state) { 605static void randseed (lua_State *L, RanState *state) {
606 lua_Unsigned seed1 = (lua_Unsigned)time(NULL); 606 lua_Unsigned seed1 = (lua_Unsigned)time(NULL);
607 lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; 607 lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
608 lua_pushinteger(L, seed1);
609 lua_pushinteger(L, seed2);
608 setseed(state->s, seed1, seed2); 610 setseed(state->s, seed1, seed2);
609} 611}
610 612
611 613
612static int math_randomseed (lua_State *L) { 614static int math_randomseed (lua_State *L) {
613 RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); 615 RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
614 if (lua_isnone(L, 1)) 616 if (lua_isnone(L, 1)) {
615 randseed(L, state); 617 randseed(L, state);
618 return 2; /* return seeds */
619 }
616 else { 620 else {
617 lua_Integer n1 = luaL_checkinteger(L, 1); 621 lua_Integer n1 = luaL_checkinteger(L, 1);
618 lua_Integer n2 = luaL_optinteger(L, 2, 0); 622 lua_Integer n2 = luaL_optinteger(L, 2, 0);
619 setseed(state->s, n1, n2); 623 setseed(state->s, n1, n2);
624 return 0;
620 } 625 }
621 return 0;
622} 626}
623 627
624 628
@@ -635,6 +639,7 @@ static const luaL_Reg randfuncs[] = {
635static void setrandfunc (lua_State *L) { 639static void setrandfunc (lua_State *L) {
636 RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); 640 RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0);
637 randseed(L, state); /* initialize with a "random" seed */ 641 randseed(L, state); /* initialize with a "random" seed */
642 lua_pop(L, 2); /* remove pushed seeds */
638 luaL_setfuncs(L, randfuncs, 1); 643 luaL_setfuncs(L, randfuncs, 1);
639} 644}
640 645
diff --git a/manual/manual.of b/manual/manual.of
index 3d2fb4fb..7f2596fa 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -7798,6 +7798,9 @@ The default for @id{y} is zero.
7798When called with no arguments, 7798When called with no arguments,
7799Lua generates a seed with 7799Lua generates a seed with
7800a weak attempt for randomness. 7800a weak attempt for randomness.
7801In this case,
7802the call returns the two seed components that were used.
7803
7801To ensure a required level of randomness to the initial state 7804To ensure a required level of randomness to the initial state
7802(or contrarily, to have a deterministic sequence, 7805(or contrarily, to have a deterministic sequence,
7803for instance when debugging a program), 7806for instance when debugging a program),
diff --git a/testes/all.lua b/testes/all.lua
index 72121e8d..bf27f106 100644
--- a/testes/all.lua
+++ b/testes/all.lua
@@ -37,8 +37,6 @@ end
37-- tests should require debug when needed 37-- tests should require debug when needed
38debug = nil 38debug = nil
39 39
40require"bwcoercion"
41
42 40
43if usertests then 41if usertests then
44 T = nil -- no "internal" tests for user tests 42 T = nil -- no "internal" tests for user tests
@@ -46,7 +44,6 @@ else
46 T = rawget(_G, "T") -- avoid problems with 'strict' module 44 T = rawget(_G, "T") -- avoid problems with 'strict' module
47end 45end
48 46
49math.randomseed(0)
50 47
51--[=[ 48--[=[
52 example of a long [comment], 49 example of a long [comment],
@@ -54,6 +51,14 @@ math.randomseed(0)
54 51
55]=] 52]=]
56 53
54print("\n\tStarting Tests")
55
56do
57 -- set random seed
58 local random_x, random_y = math.randomseed()
59 print(string.format("random seeds: %d, %d", random_x, random_y))
60end
61
57print("current path:\n****" .. package.path .. "****\n") 62print("current path:\n****" .. package.path .. "****\n")
58 63
59 64
diff --git a/testes/math.lua b/testes/math.lua
index befce12e..0c297e74 100644
--- a/testes/math.lua
+++ b/testes/math.lua
@@ -815,7 +815,7 @@ end
815-- low-level!! For the current implementation of random in Lua, 815-- low-level!! For the current implementation of random in Lua,
816-- the first call after seed 1007 should return 0x7a7040a5a323c9d6 816-- the first call after seed 1007 should return 0x7a7040a5a323c9d6
817do 817do
818 -- all computations assume at most 32-bit integers 818 -- all computations should work with 32-bit integers
819 local <const> h = 0x7a7040a5 -- higher half 819 local <const> h = 0x7a7040a5 -- higher half
820 local <const> l = 0xa323c9d6 -- lower half 820 local <const> l = 0xa323c9d6 -- lower half
821 821
@@ -840,7 +840,14 @@ do
840 assert(rand * 2^floatbits == res) 840 assert(rand * 2^floatbits == res)
841end 841end
842 842
843math.randomseed() 843do
844 -- testing return of 'randomseed'
845 local <const> x, <const> y = math.randomseed()
846 local res = math.random(0)
847 math.randomseed(x, y) -- should repeat the state
848 assert(math.random(0) == res)
849 -- keep the random seed for following tests
850end
844 851
845do -- test random for floats 852do -- test random for floats
846 local randbits = math.min(floatbits, 64) -- at most 64 random bits 853 local randbits = math.min(floatbits, 64) -- at most 64 random bits