diff options
Diffstat (limited to 'src/LivingVillage.Kernel/Rng.fs')
| -rw-r--r-- | src/LivingVillage.Kernel/Rng.fs | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/LivingVillage.Kernel/Rng.fs b/src/LivingVillage.Kernel/Rng.fs new file mode 100644 index 0000000..9564b56 --- /dev/null +++ b/src/LivingVillage.Kernel/Rng.fs @@ -0,0 +1,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' |
