1 package frost.math
2
3 ====================================================================================================
4 Provices methods for calculating pseudorandom numbers. Implementations of `Random` generally need
5 only implement the [int64()] method, with all other methods having default implementations.
6 ====================================================================================================
7 interface Random {
8 ================================================================================================
9 Provides an automatically-seeded implementation of the default random number generator. The
10 precise algorithm chosen may be system- and version-dependent and is not guaranteed to remain
11 consistent over time. Calling `Random.default()` multiple times within a single run of a program
12 may return instances which all return the same sequence; generally, you should only call this
13 method once per run of a given program.
14 ================================================================================================
15 @class
16 function default():Random {
17 return XorShift128Plus(Timer().elapsed().asInt64)
18 }
19
20 ============================================================================
21 Returns a random `Bit` (either `true` or `false` with 50% odds of each).
22
23 @returns a random bit
24 ============================================================================
25 @default
26 method bit():Bit {
27 def test := self.int64()
28 return test && 1 != 0
29 }
30
31 ================================================================================================
32 Returns a random number between [Int32.MIN] and [Int32.MAX], inclusive.
33 ================================================================================================
34 @default
35 method int32():Int32 {
36 return int64().asInt32
37 }
38
39 ================================================================================================
40 Returns a random number between [Int64.MIN] and [Int64.MAX], inclusive.
41 ================================================================================================
42 method int64():Int64
43
44 ================================================================================================
45 Returns a random `Int` between `0` and `n - 1`, inclusive. For example, `int(6)` is equivalent
46 to rolling a standard six-sided die, with return value between `0` and `5`.
47
48 @param n the range of possible values to generate
49 @returns a random number between `0` and `n - 1`
50 ================================================================================================
51 @default
52 @pre(n >= 1)
53 @post(@return >= 0 & @return < n)
54 method int(n:Int):Int {
55 if n = 1 {
56 return 0
57 }
58
59 def min := -n % n
60 loop {
61 def x := int64().asInt
62 if x >= min {
63 return x % n
64 }
65 }
66 }
67
68 ================================================================================================
69 Returns a random, uniformly distributed `Real32` between `0` (inclusive) and `1` (exclusive).
70
71 @returns a random `Real32`
72 ================================================================================================
73 @default
74 @post(@return >= 0 & @return < 1)
75 method real32():Real32 {
76 return (int32().asUInt32 >> 8) / (1 << 24)
77 }
78
79 ================================================================================================
80 Returns a random, uniformly distributed `Real64` between `0` (inclusive) and `1` (exclusive).
81
82 @returns a random `Real64`
83 ================================================================================================
84 @default
85 @post(@return >= 0 & @return < 1)
86 method real64():Real64 {
87 return (int64().toUInt64 >> 11) / (1 << 53)
88 }
89
90 }