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.

bigIntFromFloat

int_from_float.bigIntFromFloat
pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void

File

lib/compiler_rt/int_from_float.zig:79

Code

pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void {
    switch (result.len) {
        0 => return,
        inline 1...4 => |limbs_len| {
            const I = @Int(signedness, 32 * limbs_len);
            const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a)));
            result[0..limbs_len].* = switch (@import("builtin").cpu.arch.endian()) {
                .little => low_to_high,
                .big => switch (limbs_len) {
                    1 => .{low_to_high[0]},
                    2 => .{ low_to_high[1], low_to_high[0] },
                    3 => .{ low_to_high[2], low_to_high[1], low_to_high[0] },
                    4 => .{ low_to_high[3], low_to_high[2], low_to_high[1], low_to_high[0] },
                    else => comptime unreachable,
                },
            };
            return;
        },
        else => {},
    }

    // sign implicit fraction
    const significand_bits = 1 + math.floatFractionalBits(@TypeOf(a));
    const I = @Int(signedness, @as(u16, @intFromBool(signedness == .signed)) + significand_bits);

    const parts = math.frexp(a);
    const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) +
        @intFromBool(signedness == .signed and parts.exponent == 32 * result.len);
    const exponent: usize = @intCast(@max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0));
    const int: I = @intFromFloat(switch (exponent) {
        0 => a,
        else => math.ldexp(parts.significand, significand_bits_adjusted_to_handle_smin),
    });
    switch (signedness) {
        .signed => {
            const endian = @import("builtin").cpu.arch.endian();
            const exponent_limb = switch (endian) {
                .little => exponent / 32,
                .big => result.len - 1 - exponent / 32,
            };
            const sign_bits: u32 = if (int < 0) math.maxInt(u32) else 0;
            @memset(result[0..exponent_limb], switch (endian) {
                .little => 0,
                .big => sign_bits,
            });
            result[exponent_limb] = sign_bits << @truncate(exponent);
            @memset(result[exponent_limb + 1 ..], switch (endian) {
                .little => sign_bits,
                .big => 0,
            });
        },
        .unsigned => @memset(result, 0),
    }
    std.mem.writePackedInt(I, std.mem.sliceAsBytes(result), exponent, int, .native);
}