code wiki / (root) / nx_prng_test.nx

nx_prng_test.nx source

↩ module page · 109 lines · 3086 B

1// nx_prng_test.nx -- smoke for nx_prng. 2 3import "syscalls.nx" 4import "nx_prng.nx" 5 6func main() -> i64 { 7 // === Test 1: same seed -> same sequence === 8 let s1: *i64 = (sys_mmap(8)) as *i64 9 let s2: *i64 = (sys_mmap(8)) as *i64 10 nx_prng_init(s1, 42) 11 nx_prng_init(s2, 42) 12 var i: i64 = 0 13 while i < 5 { 14 if nx_prng_next(s1) != nx_prng_next(s2) { return 1 } 15 i = i + 1 16 } 17 18 // === Test 2: different seeds -> different sequences === 19 nx_prng_init(s1, 1) 20 nx_prng_init(s2, 2) 21 var n_diff: i64 = 0 22 var j: i64 = 0 23 while j < 5 { 24 if nx_prng_next(s1) != nx_prng_next(s2) { n_diff = n_diff + 1 } 25 j = j + 1 26 } 27 if n_diff < 4 { return 2 } // most should differ 28 29 // === Test 3: range produces values in [0, n) === 30 nx_prng_init(s1, 12345) 31 var ok: i64 = 1 32 var k: i64 = 0 33 while k < 50 { 34 let r: i64 = nx_prng_range(s1, 100) 35 if r < 0 { ok = 0 } 36 if r >= 100 { ok = 0 } 37 k = k + 1 38 } 39 if ok != 1 { return 10 } 40 41 // === Test 4: range_lo_hi in [10, 20) === 42 var ok2: i64 = 1 43 var k2: i64 = 0 44 while k2 < 50 { 45 let r: i64 = nx_prng_range_lo_hi(s1, 10, 20) 46 if r < 10 { ok2 = 0 } 47 if r >= 20 { ok2 = 0 } 48 k2 = k2 + 1 49 } 50 if ok2 != 1 { return 11 } 51 52 // === Test 5: Bernoulli converges to p === 53 // With p = 0.5 (8192 Q14) over 200 trials, count should be roughly 100. 54 nx_prng_init(s1, 7) 55 var trials: i64 = 0 56 var hits: i64 = 0 57 while trials < 200 { 58 hits = hits + nx_prng_bernoulli(s1, 8192) 59 trials = trials + 1 60 } 61 // Allow [70, 130] range 62 if hits < 70 { return 20 } 63 if hits > 130 { return 21 } 64 65 // === Test 6: seed 0 produces non-degenerate sequence === 66 nx_prng_init(s1, 0) 67 let v1: i64 = nx_prng_next(s1) 68 let v2: i64 = nx_prng_next(s1) 69 if v1 == 0 { return 30 } 70 if v2 == 0 { return 31 } 71 if v1 == v2 { return 32 } 72 73 // === Test 7: shuffle permutes array === 74 let arr: *i64 = (sys_mmap(10 * 8)) as *i64 75 var f: i64 = 0 76 while f < 10 { 77 arr[f] = f 78 f = f + 1 79 } 80 nx_prng_init(s1, 99) 81 nx_prng_shuffle(s1, arr, 10) 82 // All values 0..9 should still be present (just permuted) 83 let seen: *i64 = (sys_mmap(10 * 8)) as *i64 84 var z: i64 = 0 85 while z < 10 { seen[z] = 0; z = z + 1 } 86 var m: i64 = 0 87 while m < 10 { 88 let v: i64 = arr[m] 89 if v < 0 { return 40 } 90 if v >= 10 { return 41 } 91 seen[v] = seen[v] + 1 92 m = m + 1 93 } 94 var c: i64 = 0 95 while c < 10 { 96 if seen[c] != 1 { return 42 } 97 c = c + 1 98 } 99 // Sanity: not the original order (with seed 99, vanishingly unlikely) 100 var moved: i64 = 0 101 var q: i64 = 0 102 while q < 10 { 103 if arr[q] != q { moved = moved + 1 } 104 q = q + 1 105 } 106 if moved < 4 { return 43 } // some movement expected 107 108 return 0 109}