Skip to content

std/rng ​

Seedable, reproducible pseudo-random numbers. std/random is a CSPRNG, unpredictable by design and impossible to replay; this is the other half, for simulations, procedural worlds, property tests and golden-frame renders, where the same seed must give the same stream on every platform. The generator is SplitMix64. It is not cryptographically secure.

milo
from "std/rng" import { Rng }

Example ​

milo
var a = Rng.new(42)
var b = Rng.new(42)
print(a.range(1, 6) == b.range(1, 6))   // true: same seed, same stream
print(a.float() < 1.0)                  // true

API reference ​

Rng ​

milo
pub struct Rng

Fields: state: u64.

Rng.bool ​

milo
fn Rng.bool(self: &mut Rng): bool

Rng.float ​

milo
fn Rng.float(self: &mut Rng): f64

Uniform in [0, 1). 53 bits of mantissa, which is every f64 value the interval can hold.

Rng.floatRange ​

milo
fn Rng.floatRange(self: &mut Rng, min: f64, max: f64): f64

Rng.int ​

milo
fn Rng.int(self: &mut Rng, max: i64): i64

Uniform in [0, max). Returns 0 when max <= 0 rather than trapping, so a caller looping over an empty range degrades instead of aborting.

Modulo, not rejection sampling: the bias is 2^-64 per unit of max, which is unmeasurable for any max a program actually passes, and rejection would make the stream length input-dependent — which breaks replay.

Rng.new ​

milo
fn Rng.new(seed: i64): Rng

A generator seeded by value. Same seed, same stream — that is the whole point of this module.

Rng.next ​

milo
fn Rng.next(self: &mut Rng): u64

Raw 64 bits, uniform.

Rng.range ​

milo
fn Rng.range(self: &mut Rng, min: i64, max: i64): i64

Uniform in [min, max], inclusive of both ends — matching Random.range.

Rng.shuffleI64 ​

milo
fn Rng.shuffleI64(self: &mut Rng, v: &mut Vec<i64>, n: i64)

Fisher-Yates over the first n entries.