README

#Random

Pseudo-random number generation based on the ChaCha8 stream cipher. Provides unbiased generation of integers, floats, booleans, and big integers, as well as Fisher-Yates shuffling.

#Overview

The Rand type wraps a Source trait object that produces 64-bit random values. By default, Rand::new() uses a ChaCha8 cipher seeded from platform entropy when available, and falls back to the default fixed seed on unsupported targets. For reproducible results, use Rand::chacha8(seed~) with the same 32-byte seed; for distinct reproducible streams, supply different seeds.

#Create

Create a generator with the default ChaCha8 source:

///|
test {
let r = @random.Rand::new()
inspect(r.uint(limit=100) < 100, content="true")
}

Supply a custom 32-byte seed for a different (but reproducible) stream:

///|
test {
let r = @random.Rand::chacha8(seed=b"0123456789abcdef0123456789abcdef")
let a = r.int()
let r2 = @random.Rand::chacha8(seed=b"0123456789abcdef0123456789abcdef")
let b = r2.int()
@test.assert_eq(a, b) // same seed → same sequence
}

#Generating Integers

int(), uint(), int64(), and uint64() each accept an optional limit parameter. When omitted (or zero), the full non-negative range is returned. When provided, the result is in [0, limit) with no modulo bias.

///|
test {
let r = @random.Rand::new()
// full range
let _ : Int = r.int() // [0, 2^31)
let _ : UInt = r.uint() // [0, 2^32)
let _ : Int64 = r.int64() // [0, 2^63)
let _ : UInt64 = r.uint64() // [0, 2^64)
// bounded
let die = r.int(limit=6) // [0, 6)
inspect(die >= 0 && die < 6, content="true")
let pct = r.uint(limit=100U)
inspect(pct < 100U, content="true")
}

#Generating Floats

double() returns a value in [0.0, 1.0) with 53-bit precision. float() returns a value in [0.0, 1.0) with 24-bit precision.

///|
test {
let r = @random.Rand::new()
let d = r.double()
inspect(d >= 0.0 && d < 1.0, content="true")
let f = r.float()
inspect(f >= (0.0 : Float) && f < (1.0 : Float), content="true")
}

#Boolean

boolean() returns true or false with equal probability.

///|
test {
let r = @random.Rand::new()
let _ : Bool = r.boolean()
}

#Shuffling

shuffle(n, swap) performs a Fisher-Yates shuffle over n elements using the provided swap callback.

///|
test {
let r = @random.Rand::new()
let a = [1, 2, 3, 4, 5]
r.shuffle(a.length(), fn(i, j) {
let t = a[i]
a[i] = a[j]
a[j] = t
})
a.sort()
@test.assert_eq(a, [1, 2, 3, 4, 5]) // same elements, just reordered
}

#BigInt

Generate a random non-negative BigInt with a given number of bits:

///|
test {
let r = @random.Rand::new()
let big = r.bigint(128)
inspect(big >= 0N, content="true")
}

#Custom Source

Implement the Source trait to plug in your own RNG backend. The trait requires a single method next(Self) -> UInt64.

///|
struct MySource {
mut value : UInt64
}

///|
impl @random.Source for MySource with fn next(self) -> UInt64 {
self.value = self.value * 6364136223846793005UL + 1UL
self.value
}

///|
test {
let gen : MySource = { value: 42 }
let r = @random.Rand::new(generator=gen as &@random.Source)
let _ = r.uint64()
}

#
Source

pub(open) trait Source {
fn next(Self) -> UInt64
}

The [Source] trait defines a method to generate random numbers.

#
Rand

type Rand

Rand is a pseudo-random number generator (PRNG) that provides various methods to generate random numbers of different types.

#
Rand::bigint

fn Rand::bigint(self : Rand, bits : Int) ->
BigInt

Generates a random positive BigInt with a specified number of bits.

Parameters:

  • rand : A random number generator that implements the Rand trait.
  • bits : The desired number of bits in the generated number.

Example:

test {
let rand = @random.Rand::new()
let n = rand.bigint(8) // Generate random 8-bit number
inspect(n.bit_length() <= 8, content="true")
}

#
Rand::boolean

fn Rand::boolean(self : Rand) -> Bool

[boolean] returns a random boolean value (true or false).

#
Rand::chacha8

fn Rand::chacha8(seed? : Bytes) -> Rand

Create a new random number generator with [seed]. @alert unsafe "Panic if seed is not 32 bytes long"

#
Rand::double

fn Rand::double(self : Rand) -> Double

[double] returns a pseudo-random 64-bit Double in the range [0.0, 1.0)

#
Rand::float

fn Rand::float(self : Rand) -> Float

[float] returns a pseudo-random 32-bit Float in the range [0.0, 1.0)

#
Rand::int

fn Rand::int(self : Rand, limit? : Int) -> Int

[int] Return a non-negative pseudo-random 31-bit integer as an Int in the range [0, 2^31) or [0, limit) if limit is provided.

Arguments

  • limit - The upper bound (exclusive) of the random number to be generated (Optional). When limit is 0, the range is [0, 2^31).

#
Rand::int64

fn Rand::int64(self : Rand, limit? : Int64) -> Int64

[int64] returns a non-negative pseudo-random 63-bit integer as an Int64 in the range [0, 2^63)

Arguments

  • limit - The upper bound (exclusive) of the random number to be generated (Optional). When limit is 0, the range is [0, 2^63).

#
Rand::new

fn Rand::new(generator? : &Source) -> Rand

Create a new random number generator with a given [Gen] source.

#
Rand::shuffle

fn Rand::shuffle(self : Rand, limit : Int, swap : (Int, Int) -> Unit) -> Unit

[shuffle] shuffles the first n elements of an array using the Fisher-Yates shuffle algorithm. The limit should not be negative.

Example

test {
let r = @random.Rand::new()
let a : FixedArray[Int] = [1, 2, 3, 4, 5]
r.shuffle(a.length(), (i : Int, j : Int) => {
let t = a[i]
a[i] = a[j]
a[j] = t
})
}

#
Rand::uint

fn Rand::uint(self : Rand, limit? : UInt) -> UInt

[uint] returns a non-negative pseudo-random 32-bit integer as a Uint in the range [0, 2^32) or [0, limit) if limit is provided.

Arguments

  • limit - The upper bound (exclusive) of the random number to be generated (Optional). When limit is 0, the range is [0, 2^32).

#
Rand::uint64

fn Rand::uint64(self : Rand, limit? : UInt64) -> UInt64

[uint64] returns a non-negative pseudo-random 64-bit integer as a Uint64 in the range [0, 2^64) or [0, limit) if limit is provided.

Arguments

  • limit - The upper bound (exclusive) of the random number to be generated (Optional). When limit is 0, the range is [0, 2^64).

#
chacha8

#deprecated("You may use `Rand::chacha8(seed~)` instead of `Rand::new(chacha8(seed~))")
fn chacha8(seed? : Bytes) -> &Source

Create a new random number generator with [seed].

#
new

#deprecated("Use `Rand::new()` instead")
fn new(seed? : Bytes) -> Rand

Create a new instance.