feature. See also
. The project being documented here (as the example) is the Zig library itself.
int_from_float.bigIntFromFloat
pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void
File
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 => {},
}
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);
}