Module: math.random

Source: ./math/random.reef


Overview

math/random - Random number generation

Provides functions for generating pseudo-random numbers. Uses Xorshift32 algorithm - a fast, pure Reef PRNG implementation. Period: 2^32-1 (approximately 4 billion values before repeating)


Functions

fn xorshift32(): uint32

fn below_u32(n: uint32): uint32

Internal: an unbiased draw in [0, n) for 1 <= n <= 2^32-1 (rejection as in arc4random_uniform: discard the 2^32 mod n lowest outputs, then reduce). n == 0 means the full 2^32 span: one raw draw.

fn random_int(): int

Returns a random non-negative integer A random non-negative int.

reef-lang#65: the comment said "mask off sign bit" and the code NEGATED instead. For a state of exactly INT_MIN, -r is INT_MIN again, so a function documented non-negative returned a negative -- and random_int_max then took a modulo of it. Masking is what the comment always described, and on a uint32 state it is the only step needed.

fn random_int_max(max: int): int

Returns a random integer in range [0, max). max <= 0 returns 0.

RB-020: this was random_int() % max, which favours small results whenever max does not divide 2^31 -- for max = 1500000000 the values below 647483648 came up 60% of the time instead of 43%. Now unbiased.

fn random_int_range(min_val: int, max_val: int): int

Returns a random integer in range [min_val, max_val] (inclusive). min_val >= max_val returns min_val.

RB-020: max_val - min_val + 1 overflowed int for spans over 2^31-1: it went negative (results outside the range) or, for INT_MIN..INT_MAX, wrapped to 0 and panicked on % 0. It was also biased like random_int_max. The span is now computed in uint32, which holds every int span, and drawn without bias.

fn random_float(): float

Returns a random float in range [0.0, 1.0)

RB-020: the divisor was 2^31 - 1, the largest random_int() itself, so a draw of 2147483647 returned exactly 1.0 (seed(1584200935) did it on the first call) -- outside the documented half-open range. Dividing by 2^31 keeps every result below 1.0.

fn random_float_range(min_val: float, max_val: float): float

Returns a random float in range [min_val, max_val)

fn random_bool(): bool

Returns a random boolean (true or false with equal probability)


Procedures

proc seed(s: int)

Seeds the random number generator with a specific value Use for reproducible sequences Note: seed must be non-zero for Xorshift to work properly

proc seed_time()

Seeds the generator unpredictably: from the OS entropy source (runtime.reef_rt_entropy) when the target has one, else from the clock.

RB-020: this used to be the clock alone, in whole seconds -- two programs started in the same second drew the same "random" sequence. The clock is now only the fallback (bare metal without an entropy hook).

This is still xorshift32: NOT for keys, tokens or anything an attacker must not predict. Use random.random (secure_*) for those.


Generated by reefc doc