code wiki / _hdl_build / nx_js_random_probe.nx

nx_js_random_probe.nx source

↩ module page · 44 lines · 3176 B

1// verify Math.random(): runs, in [0,1), deterministic (seeded), matches tree-walker. expect_exit: 0 2// license_tier: ORIGINAL 3import "nx_js_vm.nx" 4const K_MAGIC_333657: i64 = 333657 5func rw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 6func rn(v: i64) -> i64 { if v==0 { sys_write(1,"0" as *u8,1); return 0 } var m: i64=v; if m<0 { sys_write(1,"-" as *u8,1); m=0-m } let t: *u8=sys_mmap(24); var k: i64=0; while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } let o: *u8=sys_mmap(24); var q: i64=k-1; var x: i64=0; while q>=0 { o[x]=t[q]; x=x+1; q=q-1 } sys_write(1,o,x); return 0 } 7func main(argc: i64, argv: *i64) -> i64 { 8 rw("=== Math.random probe ===\n" as *u8) 9 let o: *i64 = sys_mmap(16) as *i64 10 let ot: *i64 = sys_mmap(16) as *i64 11 var pass: i64 = 0 12 var tot: i64 = 0 13 // 1) range: 1000 draws, all in [0,1) -> count in-range (should be 1000) 14 tot = tot + 1 15 let s1: *u8 = "var i=0;var c=0;while(i<1000){var r=Math.random();if(r>=0){if(r<1){c=c+1;}}i=i+1;}c" as *u8 16 compile_run(s1, o) 17 rw(" 1 in-range/1000 (VM): "); rn(o[1]) 18 if o[0]==VAL_NUM { if o[1]==1000 { pass=pass+1; rw(" ok\n" as *u8) } else { rw(" FAIL\n" as *u8) } } else { rw(" FAIL(tag)\n" as *u8) } 19 // 2) varied: consecutive draws differ (float != float), and count how many of 100 pairs differ (~100) 20 tot = tot + 1 21 let s2: *u8 = "var i=0;var c=0;while(i<100){if(Math.random()!=Math.random()){c=c+1;}i=i+1;}c" as *u8 22 compile_run(s2, o) 23 rw(" 2 pairs-differ/100 (VM): "); rn(o[1]) 24 if o[0]==VAL_NUM { if o[1]>90 { pass=pass+1; rw(" ok (varied)\n" as *u8) } else { rw(" FAIL not-varied\n" as *u8) } } else { rw(" FAIL(tag)\n" as *u8) } 25 // 3) determinism + VM==tree parity: same seeded sequence sum must match tree-walker 26 tot = tot + 1 27 compile_run(s2, o) 28 js_run_source(s2, bsl(s2), ot) 29 rw(" 3 determinism VM="); rn(o[1]); rw(" tree="); rn(ot[1]) 30 if o[1]==ot[1] { pass=pass+1; rw(" ok (VM==tree, reproducible)\n" as *u8) } else { rw(" FAIL\n" as *u8) } 31 // 4) float->int coercion (surfaced by random): |0, Math.floor, Math.ceil on computed floats (7/2=3.5). 32 tot = tot + 1 33 // expect: floor(7/2)=3, ceil(7/2)=4, (7/2)|0=3, floor(-3.5)=-4, ceil(-3.5)=-3, (0-7/2)|0=-3 34 let s4: *u8 = "var a=Math.floor(7/2);var b=Math.ceil(7/2);var c=(7/2)|0;var d=Math.floor(0-7/2);var e=Math.ceil(0-7/2);var f=(0-7/2)|0;a*1+b*10+c*100+d*1000+e*10000+f*100000" as *u8 35 compile_run(s4, o) 36 js_run_source(s4, bsl(s4), ot) 37 // 3 + 40 + 300 + (-4)*1000 + (-3)*10000 + (-3)*100000 = 3+40+300-4000-30000-300000 = -333657 38 rw(" 4 float->int (floor/ceil/|0, +/-): VM="); rn(o[1]); rw(" tree="); rn(ot[1]) 39 if o[0]==VAL_NUM { if o[1]==(0-K_MAGIC_333657) { if ot[1]==(0-K_MAGIC_333657) { pass=pass+1; rw(" ok\n" as *u8) } else { rw(" FAIL(tree)\n" as *u8) } } else { rw(" FAIL(VM)\n" as *u8) } } else { rw(" FAIL(tag)\n" as *u8) } 40 rw(" --- "); rn(pass); rw("/"); rn(tot); rw(" ---\n" as *u8) 41 if pass==tot { rw("=== GREEN: Math.random in [0,1), varied, deterministic, VM==tree ===\n" as *u8); return 0 } 42 rw("=== RED ===\n" as *u8) 43 return 1 44}