22
33Pinetime::Controllers::RNG::State Pinetime::Controllers::RNG::Seed (Pinetime::Controllers::RNG::rng_uint s,
44 Pinetime::Controllers::RNG::rng_uint i) {
5- rng.state = 0u ;
6- rng.inc = i | 1u ;
7- Generate ();
8- rng.state += s;
9- Generate ();
10- return rng;
5+ return rng = State (s, i);
116}
127
138Pinetime::Controllers::RNG::State Pinetime::Controllers::RNG::Seed () {
149 using namespace Pinetime ::Controllers;
15- Pinetime::Controllers::RNG::State new_rng;
16- new_rng.state = (RNG::rng_uint) Generate () << (sizeof (new_rng.state ) * 4 ) ^ (RNG::rng_uint) Generate ();
17- new_rng.inc = (RNG::rng_uint) Generate () << (sizeof (new_rng.inc ) * 4 ) ^ (RNG::rng_uint) Generate ();
10+ Pinetime::Controllers::RNG::State new_rng ((uint64_t ) Generate () << 32 ^ (uint64_t ) Generate (),
11+ (uint64_t ) Generate () << 32 ^ (uint64_t ) Generate ());
1812 return new_rng;
1913}
2014
21- // *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org
22- // Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
23- // Website: https://www.pcg-random.org/download.html
24- // See: https://www.apache.org/licenses/GPL-compatibility.html
25- /*
26- uint64_t oldstate = rng.state;
27- // Advance internal state
28- rng.state = oldstate * 6364136223846793005ULL + (rng.inc | 1);
29- // Calculate output function (XSH RR), uses old state for max ILP
30- uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
31- uint32_t rot = oldstate >> 59u;
32- return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
33- */
3415Pinetime::Controllers::RNG::rng_out Pinetime::Controllers::RNG::Generate () {
35- using namespace Pinetime ::Controllers;
36- // See magic numbers in https://github.com/imneme/pcg-cpp/blob/master/include/pcg_random.hpp
37- constexpr uint32_t tbits = sizeof (rng.state ) * 8 ;
38- constexpr uint32_t sbits = sizeof (rng) * 8 ;
39- constexpr uint32_t obits = sizeof (RNG::rng_out) * 8 ;
40-
41- constexpr rng_uint multiplier = tbits >= 64 ? 1442695040888963407ULL : tbits >= 32 ? 747796405U : tbits >= 16 ? 12829U : 141u ;
42-
43- constexpr uint32_t opbits = sbits - 5 >= 64 ? 5u : // 128 bits -> 5
44- sbits - 4 >= 32 ? 4u
45- : // 64 bits -> 4
46- sbits - 3 >= 16 ? 3u
47- : // 32 bits -> 3
48- sbits - 2 >= 8 ? 2u
49- : // 16 bits -> 2
50- sbits - 1 >= 1 ? 1u
51- : // 8 bits -> 1
52- 0u ;
53-
54- auto oldstate = rng.state ;
55- rng.state = oldstate * multiplier + (rng.inc | 1 );
56- // 64 bits of state, 32 output (64 - 5 = 59, 32 - 5 = 27 and floor((5+32)/2) = 18)
57- // 2^5 = 32*
58- // output = rotate<s3,s2,s1>(state ^ (state >> s1)) >> s2, state >> s3)
59- // 32 bits of state, 16 output (32 - 4 = 28, 16 - 4 = 12, and floor((4 + 16)/2) = 10)
60- // 2^4 = 16*
61- constexpr uint32_t s3 = tbits - opbits;
62- constexpr uint32_t s2 = obits - opbits;
63- constexpr uint32_t s1 = (obits + 5 ) / 2 ;
64-
65- constexpr RNG::rng_out mask = (1 << opbits) - 1 ;
66- RNG::rng_out xorshifted = ((oldstate >> s1) ^ oldstate) >> s2;
67- rng_out rot = oldstate >> s3;
68- // rotate
69- return (xorshifted >> rot) | (xorshifted << ((-rot) & mask));
16+ return rng ();
7017};
7118
72- // Lemire's Method (slight rewrite) [0, range)
19+ // See pcg-cpp/sample/codebook.cpp
7320Pinetime::Controllers::RNG::rng_out Pinetime::Controllers::RNG::GenerateBounded (Pinetime::Controllers::RNG::rng_out range) {
74- using namespace Pinetime ::Controllers;
75- rng_uint m;
76- RNG::rng_out t = (-range) % range;
77- RNG::rng_out l;
78-
79- do {
80- RNG::rng_out x = Generate ();
81- m = RNG::rng_uint (x) * RNG::rng_uint (range);
82- l = RNG::rng_out (m);
83- } while (l < t);
84-
85- return m >> (sizeof (RNG::rng_out) * 8 );
21+ return rng (range);
8622};
0 commit comments