DoxigAlpha

float

Return a floating point value evenly distributed in the range [0, 1).

Function parameters

Parameters

#
T:type

Fast unbiased random numbers.

Types

#
DefaultPrng
Fast unbiased random numbers.
DefaultCsprng
Cryptographically secure random numbers.

Functions in this namespace

Functions

#
bytes
Read random bytes into the specified buffer until full.
enumValue
Returns a random value from an enum, evenly distributed.
enumValueWithIndex
Returns a random value from an enum, evenly distributed.
int
Returns a random int `i` such that `minInt(T) <= i <= maxInt(T)`.
uintLessThanBiased
Constant-time implementation off `uintLessThan`.
uintLessThan
Returns an evenly distributed random unsigned integer `0 <= i < less_than`.
uintAtMostBiased
Constant-time implementation off `uintAtMost`.
uintAtMost
Returns an evenly distributed random unsigned integer `0 <= i <= at_most`.
intRangeLessThanBiased
Constant-time implementation off `intRangeLessThan`.
intRangeLessThan
Returns an evenly distributed random integer `at_least <= i < less_than`.
intRangeAtMostBiased
Constant-time implementation off `intRangeAtMostBiased`.
intRangeAtMost
Returns an evenly distributed random integer `at_least <= i <= at_most`.
float
Return a floating point value evenly distributed in the range [0, 1).
floatNorm
Return a floating point value normally distributed with mean = 0, stddev = 1.
floatExp
Return an exponentially distributed float with a rate parameter of 1.
shuffle
Shuffle a slice into a random order.
shuffleWithIndex
Shuffle a slice into a random order, using an index of a
weightedIndex
Randomly selects an index into `proportions`, where the likelihood of each
limitRangeBiased
Convert a random integer 0 <= random_int <= maxValue(T),

Source

Implementation

#
pub fn float(r: Random, comptime T: type) T {
    // Generate a uniformly random value for the mantissa.
    // Then generate an exponentially biased random value for the exponent.
    // This covers every possible value in the range.
    switch (T) {
        f32 => {
            // Use 23 random bits for the mantissa, and the rest for the exponent.
            // If all 41 bits are zero, generate additional random bits, until a
            // set bit is found, or 126 bits have been generated.
            const rand = r.int(u64);
            var rand_lz = @clz(rand);
            if (rand_lz >= 41) {
                @branchHint(.unlikely);
                rand_lz = 41 + @clz(r.int(u64));
                if (rand_lz == 41 + 64) {
                    @branchHint(.unlikely);
                    // It is astronomically unlikely to reach this point.
                    rand_lz += @clz(r.int(u32) | 0x7FF);
                }
            }
            const mantissa: u23 = @truncate(rand);
            const exponent = @as(u32, 126 - rand_lz) << 23;
            return @bitCast(exponent | mantissa);
        },
        f64 => {
            // Use 52 random bits for the mantissa, and the rest for the exponent.
            // If all 12 bits are zero, generate additional random bits, until a
            // set bit is found, or 1022 bits have been generated.
            const rand = r.int(u64);
            var rand_lz: u64 = @clz(rand);
            if (rand_lz >= 12) {
                rand_lz = 12;
                while (true) {
                    // It is astronomically unlikely for this loop to execute more than once.
                    const addl_rand_lz = @clz(r.int(u64));
                    rand_lz += addl_rand_lz;
                    if (addl_rand_lz != 64) {
                        @branchHint(.likely);
                        break;
                    }
                    if (rand_lz >= 1022) {
                        rand_lz = 1022;
                        break;
                    }
                }
            }
            const mantissa = rand & 0xFFFFFFFFFFFFF;
            const exponent = (1022 - rand_lz) << 52;
            return @bitCast(exponent | mantissa);
        },
        else => @compileError("unknown floating point type"),
    }
}