Skip to content

Commit 3254987

Browse files
committed
rand: add missing i32 APIs, corresponding to the int ones
1 parent b6b9654 commit 3254987

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

vlib/rand/rand.v

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ pub fn (mut rng PRNG) read(mut buf []u8) {
4242
read_internal(mut rng, mut buf)
4343
}
4444

45-
// u32n returns a uniformly distributed pseudorandom 32-bit signed positive `u32` in range `[0, max)`.
45+
// i32n returns a uniformly distributed pseudorandom 32-bit signed positive `i32` in range `[0, max)`.
46+
@[inline]
47+
pub fn (mut rng PRNG) i32n(max i32) !i32 {
48+
return i32(rng.intn(max)!)
49+
}
50+
51+
// u32n returns a uniformly distributed pseudorandom 32-bit unsigned positive `u32` in range `[0, max)`.
4652
@[inline]
4753
pub fn (mut rng PRNG) u32n(max u32) !u32 {
4854
if max == 0 {
@@ -138,6 +144,12 @@ pub fn (mut rng PRNG) i16() i16 {
138144
return i16(rng.u16())
139145
}
140146

147+
// i32 returns a (possibly negative) pseudorandom 32-bit `i32`.
148+
@[inline]
149+
pub fn (mut rng PRNG) i32() i32 {
150+
return i32(rng.u32())
151+
}
152+
141153
// int returns a (possibly negative) pseudorandom 32-bit `int`.
142154
@[inline]
143155
pub fn (mut rng PRNG) int() int {
@@ -190,6 +202,16 @@ pub fn (mut rng PRNG) int_in_range(min int, max int) !int {
190202
return min + rng.intn(max - min)!
191203
}
192204

205+
// int_in_range returns a pseudorandom `int` in range `[min, max)`.
206+
@[inline]
207+
pub fn (mut rng PRNG) i32_in_range(min i32, max i32) !i32 {
208+
if max <= min {
209+
return error('max must be greater than min')
210+
}
211+
// This supports negative ranges like [-10, -5) because the difference is positive
212+
return min + i32(rng.intn(max - min)!)
213+
}
214+
193215
// i64_in_range returns a pseudorandom `i64` in range `[min, max)`.
194216
@[inline]
195217
pub fn (mut rng PRNG) i64_in_range(min i64, max i64) !i64 {
@@ -564,11 +586,21 @@ pub fn i16() i16 {
564586
return default_rng.i16()
565587
}
566588

589+
// i32 returns a uniformly distributed pseudorandom 32-bit signed (possibly negative) `i32`.
590+
pub fn i32() i32 {
591+
return default_rng.i32()
592+
}
593+
567594
// int returns a uniformly distributed pseudorandom 32-bit signed (possibly negative) `int`.
568595
pub fn int() int {
569596
return default_rng.int()
570597
}
571598

599+
// i32n returns a uniformly distributed pseudorandom 32-bit signed positive `i32` in range `[0, max)`.
600+
pub fn i32n(max i32) !i32 {
601+
return default_rng.i32n(max)
602+
}
603+
572604
// intn returns a uniformly distributed pseudorandom 32-bit signed positive `int` in range `[0, max)`.
573605
pub fn intn(max int) !int {
574606
return default_rng.intn(max)
@@ -580,6 +612,12 @@ pub fn int_in_range(min int, max int) !int {
580612
return default_rng.int_in_range(min, max)
581613
}
582614

615+
// int_in_range returns a uniformly distributed pseudorandom 32-bit signed int in range `[min, max)`.
616+
// Both `min` and `max` can be negative, but we must have `min < max`.
617+
pub fn i32_in_range(min i32, max i32) !i32 {
618+
return default_rng.i32_in_range(min, max)
619+
}
620+
583621
// int31 returns a uniformly distributed pseudorandom 31-bit signed positive `int`.
584622
pub fn int31() int {
585623
return default_rng.int31()

vlib/rand/random_numbers_test.v

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ fn test_rand_intn() {
7171
}
7272
}
7373

74+
fn test_rand_i32n() {
75+
max := i32(2525642)
76+
for _ in 0 .. rnd_count {
77+
value := rand.i32n(max) or { panic("Couldn't obtain i32") }
78+
assert value >= 0
79+
assert value < max
80+
}
81+
}
82+
7483
fn test_rand_i64n() {
7584
max := i64(3246727724653636)
7685
for _ in 0 .. rnd_count {
@@ -90,6 +99,16 @@ fn test_rand_int_in_range() {
9099
}
91100
}
92101

102+
fn test_rand_i32_in_range() {
103+
min := i32(-4252)
104+
max := i32(23054962)
105+
for _ in 0 .. rnd_count {
106+
value := rand.i32_in_range(min, max) or { panic("Couldn't obtain i32 in range") }
107+
assert value >= min
108+
assert value < max
109+
}
110+
}
111+
93112
fn test_rand_i64_in_range() {
94113
min := i64(-24095)
95114
max := i64(324058)
@@ -324,7 +343,9 @@ fn test_rand_ascii() {
324343
fn ensure_same_output(mut rng rand.PRNG) {
325344
for _ in 0 .. 100 {
326345
assert rand.int() == rng.int()
346+
assert rand.i32() == rng.i32()
327347
assert rand.intn(45) or { 0 } == rng.intn(45) or { 0 }
348+
assert rand.i32n(45) or { 0 } == rng.i32n(45) or { 0 }
328349
assert rand.u64() == rng.u64()
329350
assert rand.f64() == rng.f64()
330351
assert rand.u32n(25) or { 0 } == rng.u32n(25) or { 0 }

vlib/rand/sys/system_rng_test.v

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,20 @@ fn test_sys_rng_intn() {
178178
}
179179
}
180180

181+
fn test_sys_rng_i32n() {
182+
max := i32(2525642)
183+
for seed in seeds {
184+
seed_data := [seed]
185+
mut rng := &rand.PRNG(&sys.SysRNG{})
186+
rng.seed(seed_data)
187+
for _ in 0 .. range_limit {
188+
value := rng.i32n(max) or { panic("Couldn't obtain i32") }
189+
assert value >= 0
190+
assert value < max
191+
}
192+
}
193+
}
194+
181195
fn test_sys_rng_i64n() {
182196
max := i64(3246727724653636)
183197
for seed in seeds {
@@ -207,6 +221,21 @@ fn test_sys_rng_int_in_range() {
207221
}
208222
}
209223

224+
fn test_sys_rng_i32_in_range() {
225+
min := i32(-4252)
226+
max := i32(23054962)
227+
for seed in seeds {
228+
seed_data := [seed]
229+
mut rng := &rand.PRNG(&sys.SysRNG{})
230+
rng.seed(seed_data)
231+
for _ in 0 .. range_limit {
232+
value := rng.i32_in_range(min, max) or { panic("Couldn't obtain i32 in range") }
233+
assert value >= min
234+
assert value < max
235+
}
236+
}
237+
}
238+
210239
fn test_sys_rng_i64_in_range() {
211240
min := i64(-24095)
212241
max := i64(324058)

0 commit comments

Comments
 (0)