const std = @import("std");
pub fn BiasedFp(comptime T: type) type {
    const MantissaT = mantissaType(T);
    return struct {
        const Self = @This();
        
        f: MantissaT,
        
        e: i32,
        pub fn zero() Self {
            return .{ .f = 0, .e = 0 };
        }
        pub fn zeroPow2(e: i32) Self {
            return .{ .f = 0, .e = e };
        }
        pub fn inf(comptime FloatT: type) Self {
            return .{ .f = 0, .e = (1 << std.math.floatExponentBits(FloatT)) - 1 };
        }
        pub fn eql(self: Self, other: Self) bool {
            return self.f == other.f and self.e == other.e;
        }
        pub fn toFloat(self: Self, comptime FloatT: type, negative: bool) FloatT {
            var word = self.f;
            word |= @intCast(MantissaT, self.e) << std.math.floatMantissaBits(FloatT);
            var f = floatFromUnsigned(FloatT, MantissaT, word);
            if (negative) f = -f;
            return f;
        }
    };
}
pub fn floatFromUnsigned(comptime T: type, comptime MantissaT: type, v: MantissaT) T {
    return switch (T) {
        f16 => @bitCast(f16, @truncate(u16, v)),
        f32 => @bitCast(f32, @truncate(u32, v)),
        f64 => @bitCast(f64, @truncate(u64, v)),
        f128 => @bitCast(f128, v),
        else => unreachable,
    };
}
pub fn Number(comptime T: type) type {
    return struct {
        exponent: i64,
        mantissa: mantissaType(T),
        negative: bool,
        
        many_digits: bool,
        
        hex: bool,
    };
}
pub fn isEightDigits(v: u64) bool {
    const a = v +% 0x4646_4646_4646_4646;
    const b = v -% 0x3030_3030_3030_3030;
    return ((a | b) & 0x8080_8080_8080_8080) == 0;
}
pub fn isDigit(c: u8, comptime base: u8) bool {
    std.debug.assert(base == 10 or base == 16);
    return if (base == 10)
        '0' <= c and c <= '9'
    else
        '0' <= c and c <= '9' or 'a' <= c and c <= 'f' or 'A' <= c and c <= 'F';
}
pub fn mantissaType(comptime T: type) type {
    return switch (T) {
        f16, f32, f64 => u64,
        f128 => u128,
        else => unreachable,
    };
}