Modules

Random

moduleSource
macOSLinuxWindowswasm

#import "Random";

A fast 128-bit multiplicative generator for non-cryptographic random numbers.

Every procedure comes in two forms: one that takes a *Random_State of your own and one without a state that uses context.mcg_state (the module adds that field to the context, so each thread and each context copy has its own stream). The sequence is fully determined by the seed. A context that is never seeded starts from the same state every run, so seed from the clock when runs should differ. Nothing here is suitable for cryptography, and a state must not be shared between threads without a lock.

Procedures#

random_seed6 overloads
(state: *Random_State, new_seed: u64)

Starts the generator from new_seed. A u64 seed fully determines the stream, as does a Random_State, which is copied with its low half forced odd, or a time value (low and high are copied the same way).

a, b: Random_State;
random_seed(*a, cast(u64) 7);
random_seed(*b, cast(u64) 7);
assert(random_get(*a) == random_get(*b));

Time :: struct { low: u64; high: s64; }
random_seed(*a, Time.{ 4, 9 });
assert(a.low == 5 && a.high == 9);
↗
(state: *Random_State) -> float64

A float64 in [0, 1) from all 64 random bits, rounding down to the largest value below 1 when the division would round up to 1. The values are not evenly spaced: the float64 grid is finer near 0 than near 1, so prefer random_get_zero_to_one_open_new when an even grid matters.

(state: *Random_State, min: float, max: float) -> float

A float between min and max, both ends possible, computed as min + (max - min) * r and clamped back into the range if rounding strays.

state: Random_State;
random_seed(*state, cast(u64) 5);
for 1..1000 {
    v := random_get_within_range(*state, -2.0, 3.0);
    assert(v >= -2 && v <= 3);
}
assert(random_get_within_range(*state, 4.0, 4.0) == 4);
w := random_get_within_range(*state, 3.0, -2.0);
assert(w >= -2 && w <= 3);
↗

Types#

:: struct

The generator's 128-bit state, as two halves. Seed it with random_seed before drawing: an all-zero state (a plain state: Random_State;) is a fixed point of the generator and only ever yields zero.

:: struct

What random_seed accepts for a seed from the clock: any struct with a u64 named low and an s64 named high, such as an Apollo_Time.