lib.bend source
lib.bend on the hub · documented module
# Prng — tiny seeded xorshift32 for Bend 2.0.2.## Base only; no termination escapes. State is a single U32. Seed 0 aliases# seed 1 because raw xorshift32 is stuck at the zero fixed point.## next returns (value, new_prng) where value equals the new state.# next_bounded uses U32.mod; max 0 yields value 0 while still advancing.# next_f32 maps the top 24 bits into [0, 1) via U32.to_f32 (opaque to ==).import Basetype Prng is Data: Prng{state: U32}def Prng.seed(+s: U32) -> Prng: Prng{Bool.pick(U32, U32.is_zero(s), 1, s)}def Prng.step(+x: U32) -> U32: +x1 = U32.xor(x, U32.shln(x, 13n)) +x2 = U32.xor(x1, U32.shrn(x1, 17n)) U32.xor(x2, U32.shln(x2, 5n))def Prng.next(p: Prng) -> U32 & Prng: match p: case Prng{x}: +y = Prng.step(x) (y, Prng{y})def Prng.next_value.go(r: U32 & Prng) -> U32: (v, p2) = r vdef Prng.next_value(p: Prng) -> U32: Prng.next_value.go(Prng.next(p))def Prng.next_state.go(r: U32 & Prng) -> Prng: (v, p2) = r p2def Prng.next_state(p: Prng) -> Prng: Prng.next_state.go(Prng.next(p))# When max is 0, return 0 (documented); state still advances.def Prng.next_bounded.go(+max: U32, r: U32 & Prng) -> U32 & Prng: (v, p2) = r (Bool.pick(U32, U32.is_zero(max), 0, U32.mod(v, max)), p2)def Prng.next_bounded(p: Prng, +max: U32) -> U32 & Prng: Prng.next_bounded.go(max, Prng.next(p))def Prng.next_bounded_value.go(r: U32 & Prng) -> U32: (v, p2) = r vdef Prng.next_bounded_value(p: Prng, +max: U32) -> U32: Prng.next_bounded_value.go(Prng.next_bounded(p, max))# Unit interval via top 24 bits / 2^24. F32 ops are opaque to ==.def Prng.next_f32.go(r: U32 & Prng) -> F32 & Prng: (v, p2) = r (F32.div(U32.to_f32(U32.shrn(v, 8n)), 16777216.0), p2)def Prng.next_f32(p: Prng) -> F32 & Prng: Prng.next_f32.go(Prng.next(p))def Prng.state(p: Prng) -> U32: match p: case Prng{state}: state