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.

exp2f

exp2.exp2f
pub fn exp2f(x: f32) callconv(.c) f32

File

lib/compiler_rt/exp2.zig:34

Code

pub fn exp2f(x: f32) callconv(.c) f32 {
    const tblsiz: u32 = @intCast(exp2ft.len);
    const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
    const P1: f32 = 0x1.62e430p-1;
    const P2: f32 = 0x1.ebfbe0p-3;
    const P3: f32 = 0x1.c6b348p-5;
    const P4: f32 = 0x1.3b2c9cp-7;

    const u: u32 = @bitCast(x);
    const ix = u & 0x7FFFFFFF;

    // |x| > 126
    if (ix > 0x42FC0000) {
        // nan
        if (ix > 0x7F800000) {
            return x;
        }
        // x >= 128
        if (u >= 0x43000000 and u < 0x80000000) {
            return x * 0x1.0p127;
        }
        // x < -126
        if (u >= 0x80000000) {
            if (u >= 0xC3160000 or u & 0x000FFFF != 0) {
                if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x);
            }
            // x <= -150
            if (u >= 0xC3160000) {
                return 0;
            }
        }
    }
    // |x| <= 0x1p-25
    else if (ix <= 0x33000000) {
        return 1.0 + x;
    }

    // NOTE: musl relies on unsafe behaviours which are replicated below
    // (addition/bit-shift overflow). Appears that this produces the
    // intended result but should confirm how GCC/Clang handle this to ensure.

    var uf = x + redux;
    var i_0: u32 = @bitCast(uf);
    i_0 +%= tblsiz / 2;

    const k = i_0 / tblsiz;
    const uk: f64 = @bitCast(@as(u64, 0x3FF + k) << 52);
    i_0 &= tblsiz - 1;
    uf -= redux;

    const z: f64 = x - uf;
    var r: f64 = exp2ft[@intCast(i_0)];
    const t: f64 = r * z;
    r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
    return @floatCast(r * uk);
}