code wiki / _hdl_build / _f64_atan_gate_authored.nx
_f64_atan_gate_authored.nx source
↩ module page · 129 lines · 5574 B
1// _f64_atan_gate_authored.nx -- ME1 atan gate: TEAM-AUTHORED kernel (_pe_f64atan,
2// MATH_KERNEL/ATAN emitter) vs the LIVE sovereign bigfloat oracle
3// (nx_bigfloat120_atan -- self-anchored, no python). Pure Nishi end to end.
4// TOTAL DOMAIN: fixed edges (anchor points, fold seam at 41/16, subnormals,
5// huge, specials) + 300 banded xorshift points over the full exponent range.
6// ULP via the signed ordered map. GREEN iff max ULP <= 1.
7// Markers: ATBAD x= exp= got= ulp= / ATAN-ULP ... / ATAN-GATE verdict=GREEN|RED
8
9import "nx_syscalls.nx"
10import "nx_f64.nx"
11import "nx_f64_div.nx"
12import "nx_f64_cvt.nx"
13import "nx_bigfloat120.nx"
14import "nx_bigfloat120_div.nx"
15import "nx_bigfloat120_trig.nx"
16import "nx_bigfloat120_atan.nx"
17import "_pe_f64atan.nx"
18
19func atg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
20func atg_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }; let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48; k = 1 }; while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 }; var i: i64 = 0; while i < k { bb[i] = t[k-1-i]; i = i + 1 }; sys_write(1, bb, k); return 0 }
21func atg_puthex(v: i64) -> i64 { let bb: *u8 = sys_mmap(20); var i: i64 = 0; while i < 16 { let nib: i64 = (v >> ((15 - i) * 4)) & 15; if nib < 10 { bb[i] = 48 + nib } else { bb[i] = 55 + nib } i = i + 1 } sys_write(1, bb, 16); return 0 }
22
23func atg_rng(state: *i64) -> i64 {
24 var s: i64 = state[0]
25 s = s ^ ((s >> 12) & 0x000FFFFFFFFFFFFF)
26 s = s ^ (s << 25)
27 s = s ^ ((s >> 27) & 0x0000001FFFFFFFFF)
28 state[0] = s
29 return s * 2685821657736338717
30}
31
32func atg_ord(v: i64) -> i64 {
33 if v >= 0 { return v }
34 return (1 << 63) - v
35}
36
37func atg_ulp(got: i64, want: i64) -> i64 {
38 if got == want { return 0 }
39 var u: i64 = atg_ord(got) - atg_ord(want)
40 if u < 0 { u = 0 - u }
41 return u
42}
43
44func main() -> i64 {
45 let xs: *i64 = sys_mmap(8 * 512) as *i64
46 var n: i64 = 0
47 // specials + edges
48 xs[n] = 0x7FF8000000000000; n = n + 1 // NaN
49 xs[n] = 0x7FF0000000000000; n = n + 1 // +inf
50 xs[n] = 0xFFF0000000000000; n = n + 1 // -inf
51 xs[n] = 0; n = n + 1 // +0
52 xs[n] = 1 << 63; n = n + 1 // -0
53 xs[n] = 1; n = n + 1 // min subnormal
54 xs[n] = 0x000FFFFFFFFFFFFF; n = n + 1 // max subnormal
55 xs[n] = 0x0010000000000000; n = n + 1 // min normal
56 xs[n] = 0x7FEFFFFFFFFFFFFF; n = n + 1 // max finite
57 xs[n] = 0x3FF0000000000000; n = n + 1 // 1.0 (anchor j=8)
58 xs[n] = 0xBFF0000000000000; n = n + 1 // -1.0
59 xs[n] = 0x3FEFFFFFFFFFFFFF; n = n + 1 // 1 - ulp
60 xs[n] = 0x3FF0000000000001; n = n + 1 // 1 + ulp
61 xs[n] = 0x4004800000000000; n = n + 1 // 41/16 fold seam
62 xs[n] = 0x40047FFFFFFFFFFF; n = n + 1 // seam - ulp
63 xs[n] = 0x4004800000000001; n = n + 1 // seam + ulp
64 xs[n] = 0x3FC0000000000000; n = n + 1 // 1/8 (anchor j=1)
65 xs[n] = 0x3FB0000000000000; n = n + 1 // 1/16 (j 0/1 boundary)
66 xs[n] = 0x3FD8000000000000; n = n + 1 // 3/8 (anchor j=3)
67 xs[n] = 0x4000000000000000; n = n + 1 // 2.0 (anchor j=16)
68 xs[n] = 0xC003000000000000; n = n + 1 // -2.375 (anchor j=19)
69 xs[n] = 0x3E50000000000000; n = n + 1 // 2^-26 (round-to-x zone)
70 // banded random over the full domain, random signs
71 let st: *i64 = sys_mmap(16) as *i64
72 st[0] = 16180339887498948482
73 var j: i64 = 0
74 while j < 300 {
75 var raw: i64 = atg_rng(st)
76 var efr: i64 = 0
77 let band: i64 = raw & 3
78 if band == 0 { efr = 1021 + (raw & 3) } // 0.25 .. 4: seam region
79 if band == 1 { efr = 1015 + (raw & 15) } // 2^-8 .. 2^8
80 if band == 2 { efr = 960 + (raw & 63) } // small
81 if band == 3 { efr = 1026 + (raw & 511) } // 2^3 .. 2^514: fold path
82 raw = (efr << 52) | (atg_rng(st) & 0x000FFFFFFFFFFFFF)
83 if (atg_rng(st) & 1) == 1 { raw = raw | (1 << 63) }
84 xs[n] = raw
85 n = n + 1
86 j = j + 1
87 }
88
89 var a_exact: i64 = 0
90 var a_u1: i64 = 0
91 var a_worse: i64 = 0
92 var a_max: i64 = 0
93 var i: i64 = 0
94 while i < n {
95 let x: i64 = xs[i]
96 let aw: i64 = bf_atan_f64(x)
97 let ag: i64 = nx_f64_atan(x)
98 let au: i64 = atg_ulp(ag, aw)
99 if au == 0 { a_exact = a_exact + 1 }
100 if au == 1 { a_u1 = a_u1 + 1 }
101 if au > 1 {
102 a_worse = a_worse + 1
103 if a_worse <= 20 {
104 atg_puts("ATBAD x=" as *u8); atg_puthex(x)
105 atg_puts(" exp=" as *u8); atg_puthex(aw)
106 atg_puts(" got=" as *u8); atg_puthex(ag)
107 atg_puts(" ulp=" as *u8); atg_putn(au)
108 atg_puts("\n" as *u8)
109 }
110 }
111 if au > a_max { a_max = au }
112 i = i + 1
113 }
114
115 atg_puts("ATAN-ULP total=" as *u8); atg_putn(n)
116 atg_puts(" exact=" as *u8); atg_putn(a_exact)
117 atg_puts(" ulp1=" as *u8); atg_putn(a_u1)
118 atg_puts(" worse=" as *u8); atg_putn(a_worse)
119 atg_puts(" max=" as *u8); atg_putn(a_max)
120 atg_puts("\n" as *u8)
121 if a_worse == 0 {
122 atg_puts("ATAN-GATE verdict=GREEN\n" as *u8)
123 return 0
124 }
125 atg_puts("ATAN-GATE verdict=RED\n" as *u8)
126 var rc: i64 = a_worse
127 if rc > 100 { rc = 100 }
128 return rc
129}