Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
5704-Increase-mwc59-seed-range-to-58-bits.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5704-Increase-mwc59-seed-range-to-58-bits.patch of Package erlang
From 6949861e00c48f5cae13218bd051a572850660a6 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen <raimo@erlang.org> Date: Tue, 10 May 2022 16:25:10 +0200 Subject: [PATCH 4/8] Increase mwc59 seed range to 58 bits To hash the seed into 58 bits and then add 1 is better than hashing into 57 bits and then bor 1 bsl 58. 58 bits is more familiar and twice as large. --- lib/stdlib/doc/src/rand.xml | 4 ++-- lib/stdlib/src/rand.erl | 27 +++++++++++++++------------ lib/stdlib/test/rand_SUITE.erl | 10 +++++----- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml index 7eb6a164c8..8b9b924366 100644 --- a/lib/stdlib/doc/src/rand.xml +++ b/lib/stdlib/doc/src/rand.xml @@ -1064,8 +1064,8 @@ end.</pre> <desc> <p> Returns a generator state <c><anno>CX</anno></c>. - It is set it to <c><anno>S</anno></c>, after folding it - into the state's range, if out of range. + <c><anno>S</anno></c> is hashed to create the generator state, + to avoid that similar seeds create similar sequences. </p> <p> Without <c><anno>S</anno></c>, diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl index 14e4f7eb74..ac61acd955 100644 --- a/lib/stdlib/src/rand.erl +++ b/lib/stdlib/src/rand.erl @@ -1533,29 +1533,32 @@ mwc59_value(CX1) -> % when is_integer(CX1), 1 =< CX1, CX1 < ?MWC59_P -> -spec mwc59_float(CX :: mwc59_state()) -> V :: float(). mwc59_float(CX1) -> - mwc59_value(CX1) * (1/(1 bsl 59)). + CX = ?MASK(59, CX1), + CX2 = CX bxor ?BSL(59, CX, ?MWC59_XS1), + CX3 = CX2 bxor ?BSL(59, CX2, ?MWC59_XS2), + (CX3 bsr (59-53)) * ?TWO_POW_MINUS53. -spec mwc59_seed() -> CX :: mwc59_state(). mwc59_seed() -> {A1, A2, A3} = default_seed(), - X1 = hash57(A1), - X2 = hash57(A2), - X3 = hash57(A3), - ?BIT(58) bor (X1 bxor X2 bxor X3). + X1 = hash58(A1), + X2 = hash58(A2), + X3 = hash58(A3), + (X1 bxor X2 bxor X3) + 1. --spec mwc59_seed(S :: 0..?MASK(57)) -> CX :: mwc59_state(). -mwc59_seed(S) when is_integer(S), 0 =< S, S =< ?MASK(57) -> - ?BIT(58) bor hash57(S). +-spec mwc59_seed(S :: 0..?MASK(58)) -> CX :: mwc59_state(). +mwc59_seed(S) when is_integer(S), 0 =< S, S =< ?MASK(58) -> + hash58(S) + 1. %% Constants a'la SplitMix64, MurMurHash, etc. %% Not that critical, just mix the bits using bijections %% (reversible mappings) to not have any two user input seeds %% become the same generator start state. %% -hash57(X) -> - X0 = ?MASK(57, X), - X1 = ?MASK(57, (X0 bxor (X0 bsr 29)) * 16#151afd7ed558ccd), - X2 = ?MASK(57, (X1 bxor (X1 bsr 29)) * 16#0ceb9fe1a85ec53), +hash58(X) -> + X0 = ?MASK(58, X), + X1 = ?MASK(58, (X0 bxor (X0 bsr 29)) * 16#351afd7ed558ccd), + X2 = ?MASK(58, (X1 bxor (X1 bsr 29)) * 16#0ceb9fe1a85ec53), X2 bxor (X2 bsr 29). diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl index e84689ea69..5f3df66bee 100644 --- a/lib/stdlib/test/rand_SUITE.erl +++ b/lib/stdlib/test/rand_SUITE.erl @@ -216,25 +216,25 @@ mwc59_api(Config) when is_list(Config) -> error({bad_return, CX1}) catch error : function_clause -> - try rand:mwc59_seed(1 bsl 57) of + try rand:mwc59_seed(1 bsl 58) of CX2 -> error({bad_return, CX2}) catch error : function_clause -> - Seed = 324109835948422043, + Seed = 11213862807209314, Seed = rand:mwc59_seed(1), mwc59_api(Seed, 1000000) end end. mwc59_api(CX0, 0) -> - CX = 394988924775693874, + CX = 182322083224642863, {CX, CX} = {CX0, CX}, V0 = rand:mwc59_value32(CX0), - V = 3767127090, + V = 2905950767, {V, V} = {V0, V}, W0 = rand:mwc59_value(CX0), - W = 418709302640385298, + W = 269866568368142303, {W, W} = {W0, W}, F0 = rand:mwc59_float(CX0), F = (W bsr (59-53)) * (1 / (1 bsl 53)), -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor