summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel/Rng.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Kernel/Rng.fs')
-rw-r--r--src/LivingVillage.Kernel/Rng.fs24
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'