code wiki / _hdl_build / _pe_f64tan.nx

_pe_f64tan.nx source

↩ module page · 156 lines · 5707 B

1// AUTHORED BY THE NISHI BUILDER (pattern: MATH_KERNEL / TAN) -- no Claude core logic. 2// All constants from the SOVEREIGN bigfloat spec (nx_mathspec_tan). v1 domain |x| < 2^20. 3// Accurate-table + double-double; exact tangent-number Taylor (no minimax). 4import "nx_syscalls.nx" 5import "nx_tier.nx" 6import "nx_f64.nx" 7import "nx_f64_div.nx" 8import "nx_f64_cvt.nx" 9const TN_SMASK: i64 = 0xFFFFFFFFF8000000 10func _tn_mul2(a: i64, b: i64, out: *i64) -> i64 { 11 let ah: i64 = a & TN_SMASK 12 let al: i64 = nx_f64_sub(a, ah) 13 let bh: i64 = b & TN_SMASK 14 let bl: i64 = nx_f64_sub(b, bh) 15 let p: i64 = nx_f64_mul(a, b) 16 var e: i64 = nx_f64_sub(nx_f64_mul(ah, bh), p) 17 e = nx_f64_add(e, nx_f64_mul(ah, bl)) 18 e = nx_f64_add(e, nx_f64_mul(al, bh)) 19 e = nx_f64_add(e, nx_f64_mul(al, bl)) 20 out[0] = p 21 out[1] = e 22 return 0 23} 24func _tn_2sum(a: i64, b: i64, out: *i64) -> i64 { 25 let s: i64 = nx_f64_add(a, b) 26 let bv: i64 = nx_f64_sub(s, a) 27 let e: i64 = nx_f64_add(nx_f64_sub(a, nx_f64_sub(s, bv)), nx_f64_sub(b, bv)) 28 out[0] = s 29 out[1] = e 30 return 0 31} 32func _tn_tab(tb: *i64) -> i64 { 33 tb[0] = 0 34 tb[1] = 4593671619917905920 35 tb[2] = 4598175219545276416 36 tb[3] = 4600427019358961664 37 tb[4] = 4602678819172646912 38 tb[5] = 4603804719079489536 39 tb[6] = 4604930618986332160 40 tb[7] = 0 41 tb[8] = 4593695223700591013 42 tb[9] = 4598271451042958422 43 tb[10] = 4600762565920553136 44 tb[11] = 4603095874924660554 45 tb[12] = 4604673773664476912 46 tb[13] = 4606566294485004012 47 tb[14] = 0 48 tb[15] = (0 - 4877474947179949392) 49 tb[16] = (0 - 4874646594127488451) 50 tb[17] = (0 - 4868978482769739392) 51 tb[18] = 4359702029082419721 52 tb[19] = (0 - 4859589607439340245) 53 tb[20] = (0 - 4868605643208884270) 54 tb[21] = 4607182418800017408 55 tb[22] = 4607253527095366650 56 tb[23] = 4607476051229208215 57 tb[24] = 4607880214998791302 58 tb[25] = 4608526501942727806 59 tb[26] = 4609526721642987662 60 tb[27] = 4611090966654505233 61 tb[28] = 0 62 tb[29] = (0 - 4858632800411268547) 63 tb[30] = (0 - 4857399076725437829) 64 tb[31] = 4357363442473848352 65 tb[32] = 4361246537643377741 66 tb[33] = 4366258138021095436 67 tb[34] = (0 - 4859648372893013672) 68 return 35 69} 70func _tn_core(ar: i64, art: i64, out: *i64) -> i64 { 71 let tk: i64 = nx_f64_add(nx_f64_mul(ar, 4620693217682128896), 4602678819172646912) 72 let j: i64 = nx_f64_to_i64(tk) 73 let tb: *i64 = sys_mmap(8 * 35) as *i64 74 _tn_tab(tb) 75 let d0: i64 = nx_f64_sub(ar, tb[j]) 76 let dd: *i64 = sys_mmap(16) as *i64 77 _tn_2sum(d0, art, dd) 78 let dh: i64 = dd[0] 79 let dl: i64 = dd[1] 80 let z: i64 = nx_f64_mul(dh, dh) 81 var q: i64 = 4564356673986852323 82 q = nx_f64_add(nx_f64_mul(q, z), 4570429305847643616) 83 q = nx_f64_add(nx_f64_mul(q, z), 4576262929202463293) 84 q = nx_f64_add(nx_f64_mul(q, z), 4581960672315445498) 85 q = nx_f64_add(nx_f64_mul(q, z), 4587938466106554908) 86 q = nx_f64_add(nx_f64_mul(q, z), 4593971859893063953) 87 q = nx_f64_add(nx_f64_mul(q, z), 4599676419421066581) 88 let tcorr: i64 = nx_f64_add(nx_f64_mul(nx_f64_mul(dh, z), q), dl) 89 let tv: *i64 = sys_mmap(16) as *i64 90 _tn_2sum(dh, tcorr, tv) 91 let th: i64 = tv[0] 92 let tl: i64 = tv[1] 93 if j == 0 { 94 out[0] = th 95 out[1] = tl 96 return 0 97 } 98 let pr: *i64 = sys_mmap(16) as *i64 99 _tn_mul2(th, tb[21 + j], pr) 100 let n1: i64 = pr[0] 101 let n2: i64 = nx_f64_add(pr[1], nx_f64_add(nx_f64_mul(th, tb[28 + j]), nx_f64_mul(tl, tb[21 + j]))) 102 _tn_mul2(tb[7 + j], th, pr) 103 let m1: i64 = pr[0] 104 let m2: i64 = nx_f64_add(pr[1], nx_f64_add(nx_f64_mul(tb[7 + j], tl), nx_f64_mul(tb[14 + j], th))) 105 let d1: i64 = nx_f64_sub(4607182418800017408, m1) 106 let d2f: i64 = m2 ^ (1 << 63) 107 let q0: i64 = nx_f64_div(n1, d1) 108 _tn_mul2(q0, d1, pr) 109 var e: i64 = nx_f64_sub(nx_f64_sub(n1, pr[0]), pr[1]) 110 e = nx_f64_add(e, n2) 111 e = nx_f64_sub(e, nx_f64_mul(q0, d2f)) 112 let ql: i64 = nx_f64_div(e, d1) 113 let sv: *i64 = sys_mmap(16) as *i64 114 _tn_2sum(tb[7 + j], q0, sv) 115 let vt: i64 = nx_f64_add(sv[1], nx_f64_add(tb[14 + j], ql)) 116 _tn_2sum(sv[0], vt, sv) 117 out[0] = sv[0] 118 out[1] = sv[1] 119 return 0 120} 121func nx_f64_tan(x: i64) -> i64 { 122 let ax: i64 = x & 0x7FFFFFFFFFFFFFFF 123 let ef: i64 = (x >> 52) & 0x7FF 124 if ef == 2047 { return 0x7FF8000000000000 } 125 if ax == 0 { return x } 126 if ef >= 1043 { return 0x7FF8000000000000 } 127 let t8: i64 = nx_f64_mul(x, 4603909380684499075) 128 var tkr: i64 = 0 129 if ((t8 >> 63) & 1) == 1 { tkr = nx_f64_sub(t8, 4602678819172646912) } else { tkr = nx_f64_add(t8, 4602678819172646912) } 130 let k: i64 = nx_f64_to_i64(tkr) 131 let kf: i64 = nx_i64_to_f64(k) 132 let r1: i64 = nx_f64_sub(x, nx_f64_mul(kf, 4609753056924401664)) 133 let r2: i64 = nx_f64_sub(r1, nx_f64_mul(kf, 4454258360616747008)) 134 let w: i64 = nx_f64_mul(kf, 4297306550709743712) 135 let rh: i64 = nx_f64_sub(r2, w) 136 let rt: i64 = nx_f64_sub(nx_f64_sub(r2, rh), w) 137 let rs: i64 = (rh >> 63) & 1 138 let ar: i64 = rh & 0x7FFFFFFFFFFFFFFF 139 var art: i64 = rt 140 if rs == 1 { art = rt ^ (1 << 63) } 141 let v: *i64 = sys_mmap(16) as *i64 142 _tn_core(ar, art, v) 143 if (k & 1) == 0 { 144 let res: i64 = nx_f64_add(v[0], v[1]) 145 if rs == 1 { return res ^ (1 << 63) } 146 return res 147 } 148 let q0: i64 = nx_f64_div(4607182418800017408, v[0]) 149 let pr: *i64 = sys_mmap(16) as *i64 150 _tn_mul2(q0, v[0], pr) 151 var e2: i64 = nx_f64_sub(nx_f64_sub(4607182418800017408, pr[0]), pr[1]) 152 e2 = nx_f64_sub(e2, nx_f64_mul(q0, v[1])) 153 let mag: i64 = nx_f64_add(q0, nx_f64_mul(q0, e2)) 154 if rs == 1 { return mag } 155 return mag ^ (1 << 63) 156}