Type Function FloatRepr [src]

Alias for std.math.float.FloatRepr

Prototype

pub fn FloatRepr(comptime Float: type) type

Parameters

Float: type

Source

pub fn FloatRepr(comptime Float: type) type { const fractional_bits = floatFractionalBits(Float); const exponent_bits = floatExponentBits(Float); return packed struct { const Repr = @This(); mantissa: StoredMantissa, exponent: BiasedExponent, sign: std.math.Sign, pub const StoredMantissa = @Type(.{ .int = .{ .signedness = .unsigned, .bits = floatMantissaBits(Float), } }); pub const Mantissa = @Type(.{ .int = .{ .signedness = .unsigned, .bits = 1 + fractional_bits, } }); pub const Exponent = @Type(.{ .int = .{ .signedness = .signed, .bits = exponent_bits, } }); pub const BiasedExponent = enum(@Type(.{ .int = .{ .signedness = .unsigned, .bits = exponent_bits, } })) { denormal = 0, min_normal = 1, zero = (1 << (exponent_bits - 1)) - 1, max_normal = (1 << exponent_bits) - 2, infinite = (1 << exponent_bits) - 1, _, pub const Int = @typeInfo(BiasedExponent).@"enum".tag_type; pub fn unbias(biased: BiasedExponent) Exponent { switch (biased) { .denormal => unreachable, else => return @bitCast(@intFromEnum(biased) -% @intFromEnum(BiasedExponent.zero)), .infinite => unreachable, } } pub fn bias(unbiased: Exponent) BiasedExponent { return @enumFromInt(@intFromEnum(BiasedExponent.zero) +% @as(Int, @bitCast(unbiased))); } }; pub const Normalized = struct { fraction: Fraction, exponent: Normalized.Exponent, pub const Fraction = @Type(.{ .int = .{ .signedness = .unsigned, .bits = fractional_bits, } }); pub const Exponent = @Type(.{ .int = .{ .signedness = .signed, .bits = 1 + exponent_bits, } }); /// This currently truncates denormal values, which needs to be fixed before this can be used to /// produce a rounded value. pub fn reconstruct(normalized: Normalized, sign: std.math.Sign) Float { if (normalized.exponent > BiasedExponent.max_normal.unbias()) return @bitCast(Repr{ .mantissa = 0, .exponent = .infinite, .sign = sign, }); const mantissa = @as(Mantissa, 1 << fractional_bits) | normalized.fraction; if (normalized.exponent < BiasedExponent.min_normal.unbias()) return @bitCast(Repr{ .mantissa = @truncate(std.math.shr( Mantissa, mantissa, BiasedExponent.min_normal.unbias() - normalized.exponent, )), .exponent = .denormal, .sign = sign, }); return @bitCast(Repr{ .mantissa = @truncate(mantissa), .exponent = .bias(@intCast(normalized.exponent)), .sign = sign, }); } }; pub const Classified = union(enum) { normalized: Normalized, infinity, nan, invalid }; fn classify(repr: Repr) Classified { return switch (repr.exponent) { .denormal => { const mantissa: Mantissa = repr.mantissa; const shift = @clz(mantissa); return .{ .normalized = .{ .fraction = @truncate(mantissa << shift), .exponent = @as(Normalized.Exponent, comptime BiasedExponent.min_normal.unbias()) - shift, } }; }, else => if (repr.mantissa <= std.math.maxInt(Normalized.Fraction)) .{ .normalized = .{ .fraction = @intCast(repr.mantissa), .exponent = repr.exponent.unbias(), } } else .invalid, .infinite => switch (repr.mantissa) { 0 => .infinity, else => .nan, }, }; } }; }