mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
rand: fix edge case, when bit length is 31 and 63, add tests for rand.intn(2147483647)!
etc (#18714)
This commit is contained in:
parent
cf323cd0ef
commit
7ab11097be
@ -55,7 +55,7 @@ pub fn (mut rng PRNG) u32n(max u32) !u32 {
|
|||||||
// the closest power of two. Then we loop until we find
|
// the closest power of two. Then we loop until we find
|
||||||
// an int in the required range
|
// an int in the required range
|
||||||
bit_len := bits.len_32(max)
|
bit_len := bits.len_32(max)
|
||||||
if bit_len == 32 {
|
if _unlikely_(bit_len == 32) {
|
||||||
for {
|
for {
|
||||||
value := rng.u32()
|
value := rng.u32()
|
||||||
if value < max {
|
if value < max {
|
||||||
@ -63,7 +63,11 @@ pub fn (mut rng PRNG) u32n(max u32) !u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mask := (u32(1) << (bit_len + 1)) - 1
|
mask := if _unlikely_(bit_len == 31) {
|
||||||
|
u32(0x7FFFFFFF)
|
||||||
|
} else {
|
||||||
|
(u32(1) << (bit_len + 1)) - 1
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
value := rng.u32() & mask
|
value := rng.u32() & mask
|
||||||
if value < max {
|
if value < max {
|
||||||
@ -81,7 +85,7 @@ pub fn (mut rng PRNG) u64n(max u64) !u64 {
|
|||||||
return error('max must be positive integer')
|
return error('max must be positive integer')
|
||||||
}
|
}
|
||||||
bit_len := bits.len_64(max)
|
bit_len := bits.len_64(max)
|
||||||
if bit_len == 64 {
|
if _unlikely_(bit_len == 64) {
|
||||||
for {
|
for {
|
||||||
value := rng.u64()
|
value := rng.u64()
|
||||||
if value < max {
|
if value < max {
|
||||||
@ -89,7 +93,11 @@ pub fn (mut rng PRNG) u64n(max u64) !u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mask := (u64(1) << (bit_len + 1)) - 1
|
mask := if _unlikely_(bit_len == 63) {
|
||||||
|
u64(0x7FFFFFFFFFFFFFFF)
|
||||||
|
} else {
|
||||||
|
(u64(1) << (bit_len + 1)) - 1
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
value := rng.u64() & mask
|
value := rng.u64() & mask
|
||||||
if value < max {
|
if value < max {
|
||||||
|
@ -454,3 +454,23 @@ fn test_element2() {
|
|||||||
assert 4 != e
|
assert 4 != e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_proper_masking() {
|
||||||
|
under32 := []int{len: 10, init: index * 0 + rand.intn(1073741823)!}
|
||||||
|
assert under32 != [0].repeat(10)
|
||||||
|
|
||||||
|
over32 := []int{len: 10, init: index * 0 + rand.intn(1073741824)!}
|
||||||
|
assert over32 != [0].repeat(10)
|
||||||
|
|
||||||
|
under64 := []i64{len: 10, init: index * 0 + rand.i64n(i64(4611686018427387903))!}
|
||||||
|
assert under64 != [i64(0)].repeat(10)
|
||||||
|
|
||||||
|
over64 := []i64{len: 10, init: index * 0 + rand.i64n(i64(4611686018427387904))!}
|
||||||
|
assert over64 != [i64(0)].repeat(10)
|
||||||
|
|
||||||
|
almost_full32 := []int{len: 10, init: index * 0 + rand.intn(2147483647)!}
|
||||||
|
assert almost_full32 != [0].repeat(10)
|
||||||
|
|
||||||
|
almost_full64 := []i64{len: 10, init: index * 0 + rand.i64n(i64(9223372036854775807))!}
|
||||||
|
assert almost_full64 != [i64(0)].repeat(10)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user