╭ log_f128.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
.. aarch64_outline_atomics.zig absv.zig absvdi2.zig absvdi2_test.zig absvsi2.zig absvsi2_test.zig absvti2.zig absvti2_test.zig addf3.zig addf3_test.zig addvdi3.zig addvsi3.zig arm.zig atomics.zig aulldiv.zig aullrem.zig bitreverse.zig bitreversedi2_test.zig bitreversesi2_test.zig bitreverseti2_test.zig bswap.zig bswapdi2_test.zig bswapsi2_test.zig bswapti2_test.zig clear_cache.zig clzdi2_test.zig clzsi2_test.zig clzti2_test.zig cmp.zig cmpdi2_test.zig cmpsi2_test.zig cmpti2_test.zig comparedf2_test.zig comparef.zig comparesf2_test.zig cos.zig count0bits.zig ctzdi2_test.zig ctzsi2_test.zig ctzti2_test.zig divc3.zig divc3_test.zig divdf3.zig divdf3_test.zig divmodei4.zig divsf3.zig divsf3_test.zig divtf3.zig divtf3_test.zig divti3_test.zig divxf3.zig divxf3_test.zig emutls.zig exp.zig exp2.zig exp_f128.zig extendf.zig extendf_test.zig fabs.zig ffsdi2_test.zig ffssi2_test.zig ffsti2_test.zig float_from_int.zig float_from_int_test.zig floor_ceil.zig fma.zig fmax.zig fmin.zig fmod.zig fmodq_test.zig fmodx_test.zig hexagon.zig int.zig int_from_float.zig int_from_float_test.zig limb64.zig log.zig log10.zig log2.zig ╭─────────────────────────────────╮ │log_f128.zig │ ╰─────────────────────────────────╯ memcpy.zig memmove.zig modti3_test.zig mulXi3.zig mulXi3_test.zig mulc3.zig mulc3_test.zig mulf3.zig mulf3_test.zig mulo.zig mulodi4_test.zig mulosi4_test.zig muloti4_test.zig mulvsi3.zig negdi2_test.zig negsi2_test.zig negti2_test.zig negv.zig negvdi2_test.zig negvsi2_test.zig negvti2_test.zig os_version_check.zig parity.zig paritydi2_test.zig paritysi2_test.zig parityti2_test.zig popcount.zig popcountdi2_test.zig popcountsi2_test.zig popcountti2_test.zig powiXf2.zig powiXf2_test.zig rem_pio2.zig rem_pio2_large.zig rem_pio2f.zig rem_pio2l.zig round.zig shift.zig shift_test.zig sin.zig sincos.zig sqrt.zig ssp.zig stack_probe.zig subvdi3.zig subvsi3.zig tan.zig trig.zig trunc.zig truncf.zig truncf_test.zig ucmpdi2_test.zig ucmpsi2_test.zig ucmpti2_test.zig udivmod.zig udivmoddi4_test.zig udivmodei4.zig udivmodsi4_test.zig udivmodti4_test.zig
1 /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" 2 /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 3 /// 4 /// https://dl.acm.org/doi/pdf/10.1145/98267.98294 5 /// 6 /// Adapted to work for f128 and bases 2 and 10 by Christophe Delage. 7 /// 8 /// This file contains the code shared between logq, log2q and log10q. 9 const log_f128 = @This(); 10 11 const std = @import("std"); 12 const math = std.math; 13 14 pub const log2size = 7; 15 pub const size = 1 << log2size; 16 17 /// Filter out special cases for log in bases {e,2,10}. 18 /// 19 /// If x is finite and positive, returns null. 20 /// Returns the appropriate NaN or inf otherwise. 21 pub fn specialCases(x: f128) ?f128 { 22 if (!math.isFinite(x)) { 23 if (math.isNan(x)) { 24 if (math.isSignalNan(x)) math.raiseInvalid(); 25 return math.nan(f128); 26 } 27 if (math.isPositiveInf(x)) return x; 28 } 29 if (x <= 0.0) { 30 if (x >= 0.0) { 31 math.raiseDivByZero(); 32 return -math.inf(f128); 33 } 34 math.raiseInvalid(); 35 return math.nan(f128); 36 } 37 38 return null; 39 } 40 41 pub const Proc1 = struct { 42 pub const Poly = struct { 43 a1: f128, 44 a3: f128, 45 a5: f128, 46 a7: f128, 47 a9: f64, 48 a11: f64, 49 }; 50 pub const HiLo = struct { hi: f128, lo: f128 }; 51 poly: Poly, 52 tab: [size + 1]HiLo, 53 }; 54 55 pub fn proc1(comptime p: Proc1, x: f128) f128 { 56 const ym = frexp2(x); 57 const y = ym.significand; 58 const m = ym.exponent; 59 60 const F0 = @round(math.ldexp(y, log2size)); 61 const j0: usize = @intFromFloat(F0); 62 const j = j0 - size; 63 const F = math.ldexp(F0, -log2size); 64 const f = y - F; 65 66 const u = (f + f) / (y + F); 67 const v = u * u; 68 const v64: f64 = @floatCast(v); 69 70 const p9 = p.poly.a9 + v64 * p.poly.a11; 71 const p7 = p.poly.a7 + v * p9; 72 const p5 = p.poly.a5 + v * p7; 73 const p3 = p.poly.a3 + v * p5; 74 75 const q = u * v * p3; 76 77 const xm: f128 = @floatFromInt(m); 78 const l_hi = xm * p.tab[128].hi + p.tab[j].hi; 79 const l_lo = xm * p.tab[128].lo + p.tab[j].lo; 80 81 if (comptime p.poly.a1 == 1.0) 82 return l_hi + (u + (q + l_lo)) 83 else 84 return l_hi + (u * p.poly.a1 + (q + l_lo)); 85 } 86 87 pub const Proc2 = struct { 88 // exp(-1 / 16) rounded down 89 pub const lo: f128 = 0.939413062813475786119710824622305; 90 // exp(1 / 16) rounded up 91 pub const hi: f128 = 1.0644944589178594295633905946428897; 92 93 pub const Poly = struct { 94 b1_hi: f128, 95 b1_lo: f128, 96 b3: f128, 97 b5: f128, 98 b7: f128, 99 b9: f128, 100 b11: f128, 101 b13: f128, 102 b15: f64, 103 b17: f64, 104 b19: f64, 105 }; 106 107 poly: Poly, 108 }; 109 110 pub fn proc2(comptime p: Proc2, x: f128) f128 { 111 std.debug.assert(Proc2.lo < x and x < Proc2.hi); 112 113 const f = x - 1.0; 114 const g = 1 / (2 + f); 115 const u = 2 * f * g; 116 const v = u * u; 117 const uv = u * v; 118 const v64: f64 = @floatCast(v); 119 120 const p17 = p.poly.b17 + v64 * p.poly.b19; 121 const p15 = p.poly.b15 + v64 * p17; 122 const p13 = p.poly.b13 + v * p15; 123 const p11 = p.poly.b11 + v * p13; 124 const p9 = p.poly.b9 + v * p11; 125 const p7 = p.poly.b7 + v * p9; 126 const p5 = p.poly.b5 + v * p7; 127 128 const q_hi = uv * p.poly.b3; 129 const q_lo = uv * v * p5; 130 131 const f_hi: f128 = @as(f64, @floatCast(f)); 132 const f_lo = f - f_hi; 133 134 const u_hi: f128 = @as(f64, @floatCast(u)); 135 const u_lo = ((2 * (f - u_hi) - u_hi * f_hi) - u_hi * f_lo) * g; 136 137 if (comptime p.poly.b1_hi == 1.0 and p.poly.b1_lo == 0.0) 138 return u_hi + (u_lo + (q_hi + q_lo)); 139 140 // t = u * p.poly.b1 141 const t_hi = u_hi * p.poly.b1_hi; 142 const t_lo = u_lo * p.poly.b1_hi + u * p.poly.b1_lo; 143 144 // y = t + q 145 const y_hi = t_hi + q_hi; 146 const y_lo = t_lo + (t_hi - y_hi + q_hi) + q_lo; 147 148 return y_hi + y_lo; 149 } 150 151 /// Returns (f, k) such that x = f * 2^k and f in [1,2). 152 /// Asserts that x is finite and positive. 153 pub fn frexp2(x: f128) math.Frexp(f128) { 154 std.debug.assert(math.isFinite(x)); 155 std.debug.assert(x > 0.0); 156 157 const bits: u128 = @bitCast(x); 158 const uexp: i32 = @intCast(bits >> 112); 159 160 std.debug.assert(uexp >= 0); 161 162 if (uexp == 0) { 163 const shift: u7 = @intCast(@clz(bits) - 15); 164 165 const exp = -@as(i32, shift) - 0x3ffe; 166 const frac: f128 = @bitCast((bits << shift) | (0x3fff << 112)); 167 return .{ .significand = frac, .exponent = exp }; 168 } 169 170 const exp = uexp - 0x3fff; 171 const frac: f128 = @bitCast((0x3fff << 112) | ((bits << 16) >> 16)); 172 return .{ .significand = frac, .exponent = exp }; 173 } 174