Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

Random

Owns an explicitly seeded deterministic noncryptographic generator.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.random

import std.random;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

Random

pub struct Random

Owns an explicitly seeded deterministic noncryptographic generator.

The SplitMix64 recurrence follows Sebastiano Vigna's public-domain reference https://prng.di.unimi.it/splitmix64.c. All seeds, including zero, are valid. Identical seeds and operation sequences reproduce the same values across targets. A copy repeats the source's remaining sequence; it is not an independent random stream. Own one generator per independently scheduled operation or synchronize mutation externally. No operation allocates, blocks, samples a clock or accesses process-global state. Do not use this generator for passwords, tokens, keys or other security-sensitive randomness.

Example

module example.random_utilities;
from std.random import Random;
// Bounds are exact binary values; NaN is excluded by NextF64's contract.
@allow("W2101")
fn Main() -> i32 {
    var First = Random.Create(0);
    var Replay = Random.Create(0);
    if First.NextU64() != 0xE220A8397B1DCDAF_u64 { return 1; }
    if Replay.NextU64() != 0xE220A8397B1DCDAF_u64 { return 2; }
    if First.TryNextBelow(0) is .Ok { Value = _ } { return 3; }
    if First.NextU64() != Replay.NextU64() { return 4; }
    if First.NextU32() != Replay.NextU32() { return 9; }
    if First.NextBool() != Replay.NextBool() { return 10; }
    var Empty: byte[0] = [];
    First.FillBytes(Empty);
    if First.NextU64() != Replay.NextU64() { return 11; }
    switch First.TryNextBelow(1) {
        case .Ok { Value = Value } => { if Value != 0 { return 12; } }
        case .Err { Error = _ } => return 13;
    }
    var Index: usize = 0;
    while Index < 64 {
        switch First.TryNextBelow(7) {
            case .Ok { Value = Value } => { if Value >= 7 { return 5; } }
            case .Err { Error = _ } => return 6;
        }
        let Unit = First.NextF64();
        if Unit < 0_f64 || Unit >= 1_f64 { return 7; }
        Index += 1;
    }
    var Bytes: byte[9] = [0_byte, 0_byte, 0_byte, 0_byte, 0_byte,
        0_byte, 0_byte, 0_byte, 0_byte];
    var Filled = Random.Create(0);
    Filled.FillBytes(Bytes);
    if Bytes[0] != 0xAF_byte || Bytes[7] != 0xE2_byte || Bytes[8] != 0xF4_byte { return 8; }
    return 0;
}

Random.Create

pub static fn Create(Seed: u64) -> Random

Starts a reproducible sequence without sampling external entropy. Seed: Explicit initial state; every u64 is valid. Return: Independent sequence state without entropy sampling or allocation.

Random.NextU64

pub fn NextU64() -> u64

Advances once and produces all64 mixed output bits. Return: Deterministic full-width output; not cryptographically secure.

Random.NextU32

pub fn NextU32() -> u32

Advances once and selects the upper32 output bits. Return: Full-width u32 output.

Random.NextBool

pub fn NextBool() -> bool

Advances once and samples the upper output bit. Return: A deterministic boolean.

Random.TryNextBelow

pub fn TryNextBelow(Bound: u64) -> Result<u64, RandomError>

Samples an unsigned exclusive bound without modulo bias. Bound: Nonzero exclusive upper bound. Return: Uniform value below Bound, or InvalidBound without state advancement. May consume multiple words. No allocation, retained borrow or native effect.

Random.NextF64

pub fn NextF64() -> f64

Samples a binary64 fraction in the half-open unit interval. Return: One of2^53 equally spaced values in [0,1), including0, excluding1. The53-bit integer converts exactly before scaling by an exact power of two.

Random.FillBytes

pub fn FillBytes(Destination: mut byte[]) -> void

Fills borrowed writable storage in low-byte-first word order. Destination: Live writable slice retained only for this call. Consumes ceil(length/8) words, discarding unused bytes of the final word. Empty input consumes none. Different chunking may produce a different sequence because this generator does not retain a partial-word cursor. Return: No value after filling every destination byte and consuming the specified generator words.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library