Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

floatFromInt

float_from_int.floatFromInt
pub fn floatFromInt(comptime T: type, x: anytype) T

File

lib/compiler_rt/float_from_int.zig:4

Code

pub fn floatFromInt(comptime T: type, x: anytype) T {
    if (x == 0) return 0;

    // Various constants whose values follow from the type parameters.
    // Any reasonable optimizer will fold and propagate all of these.
    const Z = @Int(.unsigned, @bitSizeOf(@TypeOf(x)));
    const uT = @Int(.unsigned, @bitSizeOf(T));
    const inf = math.inf(T);
    const float_bits = @bitSizeOf(T);
    const int_bits = @bitSizeOf(@TypeOf(x));
    const exp_bits = math.floatExponentBits(T);
    const fractional_bits = math.floatFractionalBits(T);
    const exp_bias = math.maxInt(@Int(.unsigned, exp_bits - 1));
    const implicit_bit = if (T != f80) @as(uT, 1) << fractional_bits else 0;
    const max_exp = exp_bias;

    // Sign
    const abs_val = @abs(x);
    const sign_bit = if (x < 0) @as(uT, 1) << (float_bits - 1) else 0;
    var result: uT = sign_bit;

    // Compute significand
    const exp = int_bits - @clz(abs_val) - 1;
    if (int_bits <= fractional_bits or exp <= fractional_bits) {
        const shift_amt = fractional_bits - @as(math.Log2Int(uT), @intCast(exp));

        // Shift up result to line up with the significand - no rounding required
        result = @as(uT, @intCast(abs_val)) << shift_amt;
        result ^= implicit_bit; // Remove implicit integer bit
    } else {
        const shift_amt: math.Log2Int(Z) = @intCast(exp - fractional_bits);
        const exact_tie: bool = @ctz(abs_val) == shift_amt - 1;

        // Shift down result and remove implicit integer bit
        result = @as(uT, @intCast((abs_val >> (shift_amt - 1)))) ^ (implicit_bit << 1);

        // Round result, including round-to-even for exact ties
        result = ((result + 1) >> 1) & ~@as(uT, @intFromBool(exact_tie));
    }

    // Compute exponent
    if ((int_bits > max_exp) and (exp > max_exp)) // If exponent too large, overflow to infinity
        return @bitCast(sign_bit | @as(uT, @bitCast(inf)));

    result += (@as(uT, exp) + exp_bias) << math.floatMantissaBits(T);

    // If the result included a carry, we need to restore the explicit integer bit
    if (T == f80) result |= 1 << fractional_bits;

    return @bitCast(sign_bit | result);
}