code wiki / (root) / nx_bigfloat120_tan.nx

nx_bigfloat120_tan.nx source

↩ module page · 58 lines · 2383 B

1// nx_bigfloat120_tan.nx -- SOVEREIGN tan oracle on the 120-bit bigfloat: 2// tan = sin/cos over the blessed trig organ's reduction (period pi handled by 3// the quadrant parity: k odd -> -cot). Positive-only core; the bigfloat entry 4// point bf_tan_xb takes an UNROUNDED bigfloat argument so the self-anchor gate 5// can test algebraic identities (half-angle, pi-shift) at full precision across 6// DIFFERENT reduction paths -- not just at f64-rounded points. 7// v1 domain |x| < 2^20 (the trig organ's Cody-Waite range; same honest refusal). 8// Near poles: r >= ~2^-61 for any f64 near k*pi/2, so cot = cos/sin stays a 9// well-conditioned bigfloat division (no overflow band in f64 tan). 10// license_tier: ORIGINAL 11 12import "nx_syscalls.nx" 13import "nx_tier.nx" 14import "nx_bigfloat120.nx" 15import "nx_bigfloat120_div.nx" 16import "nx_bigfloat120_trig.nx" 17const K_MAGIC_2047: i64 = 2047 18const K_MAGIC_1043: i64 = 1043 19 20// tan(|xb|) for positive bigfloat xb < 2^20: writes |tan| to mag, returns the 21// sign bit of tan(xb) (0/1). Zero xb -> mag zero, sign 0. 22func bf_tan_xb(mag: *i64, xb: *i64) -> i64 { 23 if bf_is_zero(xb) == 1 { return bf_copy(mag, xb) } 24 let r: *i64 = bf_new() 25 let kq: *i64 = sys_mmap(16) as *i64 26 _bf_trig_reduce(r, kq, xb) 27 let sv: *i64 = bf_new() 28 let cv: *i64 = bf_new() 29 bf_sin_r(sv, r) 30 bf_cos_r(cv, r) 31 let kk: i64 = kq[0] & 1 // tan has period pi 32 let rneg: i64 = kq[1] 33 if kk == 0 { 34 // tan(k*pi + t), t = +-r: tan(t) = +-tan(r) 35 if bf_is_zero(sv) == 1 { return bf_copy(mag, sv) } 36 bf_div(mag, sv, cv) 37 return rneg 38 } 39 // tan(k*pi + pi/2 + t) = -cot(t): t = +r -> sign 1; t = -r -> sign 0 40 bf_div(mag, cv, sv) 41 return 1 - rneg 42} 43 44// tan(raw f64) -> f64 bit pattern (|x| < 2^20; NaN past that = honest refusal) 45func bf_tan_f64(x: i64) -> i64 { 46 let ax: i64 = x & 0x7FFFFFFFFFFFFFFF 47 let ef: i64 = (x >> 52) & 0x7FF 48 let sgn: i64 = (x >> 63) & 1 49 if ef == K_MAGIC_2047 { return 0x7FF8000000000000 } 50 if ax == 0 { return x } // tan(+-0) = +-0 51 if ef >= K_MAGIC_1043 { return 0x7FF8000000000000 } // |x| >= 2^20: refused v1 52 let xb: *i64 = bf_new() 53 bf_set_f64(xb, ax) 54 let mag: *i64 = bf_new() 55 var s: i64 = bf_tan_xb(mag, xb) 56 if sgn == 1 { s = 1 - s } // tan odd 57 return bf_to_f64(mag, s, 0) 58}