code wiki / (root) / fx_exp_test.nx

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}