fx_exp_test.nx source
↩ module page · 61 lines · 2838 B
1// fx_exp_test.nx -- KAT for the fixed-point base-2 exponential family
2// (fx_exp2 / fx_exp10 / fx_expe / fx_pow), the inverse of fx_log2.
3//
4// Run via the sovereign native lane:
5// _offc/nx_compile_x86_native.elf fx_exp_test.nx > t.s
6// as t.s -o t.o && ld -o t.elf t.o && ./t.elf ; echo $?
7// Exit 0 = all assertions PASS; exit N = assertion N failed.
8// Powers of two are EXACT; irrationals/round-trips are bounded (the
9// fixed-point algorithm is deterministic, so the band is a tight
10// correctness window, not a fudge factor). Prints the key values first.
11
12import "fx.nx"
13import "nx_syscalls.nx"
14
15func within(a: i64, b: i64, tol: i64) -> i64 {
16 var d: i64 = a - b
17 if d < 0 { d = 0 - d }
18 if d <= tol { return 1 }
19 return 0
20}
21func _emit(v: i64) -> i64 {
22 let bb: *u8=sys_mmap(28); var n: i64=v; var neg: i64=0; if n<0 { neg=1; n=0-n }
23 let t2: *u8=sys_mmap(28); var t: i64=0
24 if n==0 { t2[0]=48; t=1 }
25 while n>0 { t2[t]=48+(n%10); n=n/10; t=t+1 }
26 var len: i64=0; if neg==1 { bb[0]=45; len=1 }
27 var i: i64=0; while i<t { bb[len+i]=t2[t-1-i]; i=i+1 }
28 len=len+t; bb[len]=32; sys_write(1,bb,len+1); return 0
29}
30
31func main() -> i64 {
32 // print key computed values (for calibration / inspection)
33 _emit(fx_exp2(FX_HALF)) // 2^0.5 ~ 92682
34 _emit(fx_exp2(fx_log2(FX_ONE*5))) // round-trip 5.0 ~ 327680
35 _emit(fx_exp10(FX_ONE*2)) // 10^2 ~ 6553600
36 _emit(fx_pow(FX_ONE*2, FX_ONE*10)) // 2^10 ~ 67108864
37 let nl:*u8=sys_mmap(2); nl[0]=10; sys_write(1,nl,1)
38
39 // --- exact: 2^0 = 1.0 ---
40 if fx_exp2(0) != FX_ONE { return 1 }
41 // --- exact powers of two ---
42 if fx_exp2(FX_ONE) != (FX_ONE << 1) { return 2 } // 2^1 = 2.0
43 if fx_exp2(FX_ONE * 3) != (FX_ONE << 3) { return 3 } // 2^3 = 8.0
44 if fx_exp2(FX_ONE * 10) != (FX_ONE << 10) { return 4 } // 2^10 = 1024.0
45 // --- exact below 1.0: 2^-1 = 0.5, 2^-3 = 0.125 ---
46 if fx_exp2(0 - FX_ONE) != FX_HALF { return 5 }
47 if fx_exp2(0 - (FX_ONE * 3)) != (FX_ONE >> 3) { return 6 }
48 // --- irrational: 2^0.5 = 1.41421356 ; *65536 = 92682 ---
49 if within(fx_exp2(FX_HALF), 92682, 4) != 1 { return 7 }
50 // --- round-trip exp2(log2(x)) ~= x (tight: measured error ~8 LSB) ---
51 if within(fx_exp2(fx_log2(FX_ONE*5)), FX_ONE*5, 48) != 1 { return 8 }
52 if within(fx_exp2(fx_log2(FX_ONE*7)), FX_ONE*7, 48) != 1 { return 9 }
53 // --- base-10: 10^2 = 100.0 ; *65536 = 6553600 (measured error ~64) ---
54 if within(fx_exp10(FX_ONE*2), FX_ONE*100, 256) != 1 { return 10 }
55 // --- general power: 2^10 = 1024.0 (measured EXACT) ---
56 if within(fx_pow(FX_ONE*2, FX_ONE*10), FX_ONE*1024, 64) != 1 { return 11 }
57 // --- e^1 = 2.71828 ; *65536 = 178145 (0.3% band) ---
58 if within(fx_expe(FX_ONE), 178145, 600) != 1 { return 12 }
59
60 return 0
61}