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}