1 package frost.math
2
3 ====================================================================================================
4 A fast pseudorandom number generator using a XorShift+ algorithm with a period of 2^128 - 1.
5
6 This generator is guaranteed to always produce the same random sequence when started from the same
7 seed, even across different environments and versions of Frost.
8 ====================================================================================================
9 class XorShift128Plus : Random {
10 ================================================================================================
11 The current state.
12 ================================================================================================
13 @private
14 var state1:Int64
15
16 @private
17 var state2:Int64
18
19 ================================================================================================
20 Creates a new `XorShift128Plus` with a specific seed. All `XorShift128Plus` instances created
21 with the same seed will return the same sequence of pseudorandom numbers.
22
23 @param seed the seed to use
24 ================================================================================================
25 init(seed:Int64) {
26 -- if we start with a small seed, the first few numbers tend to likewise be small. Since
27 -- manually-chosen seeds are likely to be small, let's get out of that regime.
28 state1 := seed * 6713 + 123456789
29 if state1 = 0 {
30 -- XorShift seed cannot be zero, replace with an arbitrarily-chosen value
31 state1 := 123456789
32 }
33 state2 := !!state1
34 }
35
36 @override
37 method int64():Int64 {
38 var x := state1
39 def y := state2
40 state1 := y
41 x ~~= x << 23
42 state2 := x ~~ y ~~ (x >> 17) ~~ (y >> 26)
43 return state2 +& y
44 }
45 }