diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-17 16:00:24 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-17 16:00:24 -0300 |
commit | 4eefef07ab1c136f901d816822c79336fa89336d (patch) | |
tree | ce2232ba8a09287899af1ac07af0c902800bfae6 | |
parent | 9c28ed05c95cb6854d917ac3e3ed7be9ae109480 (diff) | |
download | lua-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.c | 9 | ||||
-rw-r--r-- | manual/manual.of | 3 | ||||
-rw-r--r-- | testes/all.lua | 11 | ||||
-rw-r--r-- | testes/math.lua | 11 |
4 files changed, 27 insertions, 7 deletions
@@ -605,20 +605,24 @@ static void setseed (Rand64 *state, lua_Unsigned n1, lua_Unsigned n2) { | |||
605 | static void randseed (lua_State *L, RanState *state) { | 605 | static 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 | ||
612 | static int math_randomseed (lua_State *L) { | 614 | static 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[] = { | |||
635 | static void setrandfunc (lua_State *L) { | 639 | static 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. | |||
7798 | When called with no arguments, | 7798 | When called with no arguments, |
7799 | Lua generates a seed with | 7799 | Lua generates a seed with |
7800 | a weak attempt for randomness. | 7800 | a weak attempt for randomness. |
7801 | In this case, | ||
7802 | the call returns the two seed components that were used. | ||
7803 | |||
7801 | To ensure a required level of randomness to the initial state | 7804 | To 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, |
7803 | for instance when debugging a program), | 7806 | for 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 |
38 | debug = nil | 38 | debug = nil |
39 | 39 | ||
40 | require"bwcoercion" | ||
41 | |||
42 | 40 | ||
43 | if usertests then | 41 | if 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 |
47 | end | 45 | end |
48 | 46 | ||
49 | math.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 | ||
54 | print("\n\tStarting Tests") | ||
55 | |||
56 | do | ||
57 | -- set random seed | ||
58 | local random_x, random_y = math.randomseed() | ||
59 | print(string.format("random seeds: %d, %d", random_x, random_y)) | ||
60 | end | ||
61 | |||
57 | print("current path:\n****" .. package.path .. "****\n") | 62 | print("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 |
817 | do | 817 | do |
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) |
841 | end | 841 | end |
842 | 842 | ||
843 | math.randomseed() | 843 | do |
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 | ||
850 | end | ||
844 | 851 | ||
845 | do -- test random for floats | 852 | do -- 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 |