summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel/Rng.fs
blob: 9564b56d906041dc6c03498818f5c7daf92296d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace LivingVillage.Kernel

[<Struct>]
type RngState =
    { State: uint64 }

module Rng =

    let goldenGamma = 0x9E3779B97F4A7C15UL

    let ofSeed (seed: uint64) : RngState = { State = seed }

    let nextUInt64 (rng: RngState) : uint64 * RngState =
        let s = rng.State + goldenGamma
        let mutable z = s
        z <- (z ^^^ (z >>> 30)) * 0xBF58476D1CE4E5B9UL
        z <- (z ^^^ (z >>> 27)) * 0x94D049BB133111EBUL
        let out = z ^^^ (z >>> 31)
        out, { State = s }

    let nextFloat32 (rng: RngState) : float32 * RngState =
        let z, rng' = nextUInt64 rng
        let bits = uint32 (z >>> 40)
        float32 bits / 16777216.0f, rng'