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}