master
  1const std = @import("std");
  2const Self = @This();
  3
  4// Minimum exponent that for a fast path case, or `-⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
  5min_exponent_fast_path: comptime_int,
  6
  7// Maximum exponent that for a fast path case, or `⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
  8max_exponent_fast_path: comptime_int,
  9
 10// Maximum exponent that can be represented for a disguised-fast path case.
 11// This is `MAX_EXPONENT_FAST_PATH + ⌊(MANTISSA_EXPLICIT_BITS+1)/log2(10)⌋`
 12max_exponent_fast_path_disguised: comptime_int,
 13
 14// Maximum mantissa for the fast-path (`1 << 53` for f64).
 15max_mantissa_fast_path: comptime_int,
 16
 17// Smallest decimal exponent for a non-zero value. Including subnormals.
 18smallest_power_of_ten: comptime_int,
 19
 20// Largest decimal exponent for a non-infinite value.
 21largest_power_of_ten: comptime_int,
 22
 23// The number of bits in the significand, *excluding* the hidden bit.
 24mantissa_explicit_bits: comptime_int,
 25
 26// Minimum exponent value `-(1 << (EXP_BITS - 1)) + 1`.
 27minimum_exponent: comptime_int,
 28
 29// Round-to-even only happens for negative values of q
 30// when q ≥ −4 in the 64-bit case and when q ≥ −17 in
 31// the 32-bitcase.
 32//
 33// When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we
 34// have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have
 35// 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10.
 36//
 37// When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64
 38// so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case)
 39// or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64
 40// (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11
 41// or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase).
 42//
 43// Thus we have that we only need to round ties to even when
 44// we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10]
 45// (in the 32-bit case). In both cases,the power of five(5^|q|)
 46// fits in a 64-bit word.
 47min_exponent_round_to_even: comptime_int,
 48max_exponent_round_to_even: comptime_int,
 49
 50// Largest exponent value `(1 << EXP_BITS) - 1`.
 51infinite_power: comptime_int,
 52
 53// Following should compute based on derived calculations where possible.
 54pub fn from(comptime T: type) Self {
 55    return switch (T) {
 56        f16 => .{
 57            // Fast-Path
 58            .min_exponent_fast_path = -4,
 59            .max_exponent_fast_path = 4,
 60            .max_exponent_fast_path_disguised = 7,
 61            .max_mantissa_fast_path = 2 << std.math.floatMantissaBits(T),
 62            // Slow + Eisel-Lemire
 63            .mantissa_explicit_bits = std.math.floatFractionalBits(T),
 64            .infinite_power = 0x1f,
 65            // Eisel-Lemire
 66            .smallest_power_of_ten = -26, // TODO: refine, fails one test
 67            .largest_power_of_ten = 4,
 68            .minimum_exponent = -15,
 69            // w >= (2m+1) * 5^-q and w < 2^64
 70            // => 2m+1 > 2^11
 71            // => 2^11*5^-q < 2^64
 72            // => 5^-q < 2^53
 73            // => q >= -23
 74            .min_exponent_round_to_even = -22,
 75            .max_exponent_round_to_even = 5,
 76        },
 77        f32 => .{
 78            // Fast-Path
 79            .min_exponent_fast_path = -10,
 80            .max_exponent_fast_path = 10,
 81            .max_exponent_fast_path_disguised = 17,
 82            .max_mantissa_fast_path = 2 << std.math.floatMantissaBits(T),
 83            // Slow + Eisel-Lemire
 84            .mantissa_explicit_bits = std.math.floatFractionalBits(T),
 85            .infinite_power = 0xff,
 86            // Eisel-Lemire
 87            .smallest_power_of_ten = -65,
 88            .largest_power_of_ten = 38,
 89            .minimum_exponent = -127,
 90            .min_exponent_round_to_even = -17,
 91            .max_exponent_round_to_even = 10,
 92        },
 93        f64 => .{
 94            // Fast-Path
 95            .min_exponent_fast_path = -22,
 96            .max_exponent_fast_path = 22,
 97            .max_exponent_fast_path_disguised = 37,
 98            .max_mantissa_fast_path = 2 << std.math.floatMantissaBits(T),
 99            // Slow + Eisel-Lemire
100            .mantissa_explicit_bits = std.math.floatMantissaBits(T),
101            .infinite_power = 0x7ff,
102            // Eisel-Lemire
103            .smallest_power_of_ten = -342,
104            .largest_power_of_ten = 308,
105            .minimum_exponent = -1023,
106            .min_exponent_round_to_even = -4,
107            .max_exponent_round_to_even = 23,
108        },
109        f80 => .{
110            // Fast-Path
111            .min_exponent_fast_path = -27,
112            .max_exponent_fast_path = 27,
113            .max_exponent_fast_path_disguised = 46,
114            .max_mantissa_fast_path = 2 << std.math.floatMantissaBits(T),
115            // Slow + Eisel-Lemire
116            .mantissa_explicit_bits = std.math.floatFractionalBits(T),
117            .infinite_power = 0x7fff,
118            // Eisel-Lemire.
119            // NOTE: Not yet tested (no f80 eisel-lemire implementation)
120            .smallest_power_of_ten = -4966,
121            .largest_power_of_ten = 4932,
122            .minimum_exponent = -16382,
123            // 2^65 * 5^-q < 2^80
124            // 5^-q < 2^15
125            // => q >= -6
126            .min_exponent_round_to_even = -6,
127            .max_exponent_round_to_even = 28,
128        },
129        f128 => .{
130            // Fast-Path
131            .min_exponent_fast_path = -48,
132            .max_exponent_fast_path = 48,
133            .max_exponent_fast_path_disguised = 82,
134            .max_mantissa_fast_path = 2 << std.math.floatMantissaBits(T),
135            // Slow + Eisel-Lemire
136            .mantissa_explicit_bits = std.math.floatFractionalBits(T),
137            .infinite_power = 0x7fff,
138            // Eisel-Lemire.
139            // NOTE: Not yet tested (no f128 eisel-lemire implementation)
140            .smallest_power_of_ten = -4966,
141            .largest_power_of_ten = 4932,
142            .minimum_exponent = -16382,
143            // 2^113 * 5^-q < 2^128
144            // 5^-q < 2^15
145            // => q >= -6
146            .min_exponent_round_to_even = -6,
147            .max_exponent_round_to_even = 49,
148        },
149        else => unreachable,
150    };
151}