mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
rand: separate rand.util and rand.seed submodules (#8353)
This commit is contained in:
parent
5f2b2df546
commit
97103f680a
@ -3,7 +3,7 @@ module util
|
||||
import os
|
||||
import rand
|
||||
import rand.wyrand
|
||||
import rand.util as rutil
|
||||
import rand.seed as rseed
|
||||
|
||||
const (
|
||||
retries = 10000
|
||||
@ -26,9 +26,7 @@ pub fn temp_file(tfo TempFileOptions) ?(os.File, string) {
|
||||
}
|
||||
d = d.trim_right(os.path_separator)
|
||||
mut rng := rand.new_default(rand.PRNGConfigStruct{})
|
||||
prefix, suffix := prefix_and_suffix(tfo.pattern) or {
|
||||
return error(@FN + ' ' + err)
|
||||
}
|
||||
prefix, suffix := prefix_and_suffix(tfo.pattern) or { return error(@FN + ' ' + err) }
|
||||
for retry := 0; retry < retries; retry++ {
|
||||
path := os.join_path(d, prefix + random_number(mut rng) + suffix)
|
||||
mut mode := 'rw+'
|
||||
@ -36,7 +34,7 @@ pub fn temp_file(tfo TempFileOptions) ?(os.File, string) {
|
||||
mode = 'w+'
|
||||
}
|
||||
mut file := os.open_file(path, mode, 0o600) or {
|
||||
rng.seed(rutil.time_seed_array(2))
|
||||
rng.seed(rseed.time_seed_array(2))
|
||||
continue
|
||||
}
|
||||
if os.exists(path) && os.is_file(path) {
|
||||
@ -64,13 +62,11 @@ pub fn temp_dir(tdo TempFileOptions) ?string {
|
||||
}
|
||||
d = d.trim_right(os.path_separator)
|
||||
mut rng := rand.new_default(rand.PRNGConfigStruct{})
|
||||
prefix, suffix := prefix_and_suffix(tdo.pattern) or {
|
||||
return error(@FN + ' ' + err)
|
||||
}
|
||||
prefix, suffix := prefix_and_suffix(tdo.pattern) or { return error(@FN + ' ' + err) }
|
||||
for retry := 0; retry < retries; retry++ {
|
||||
path := os.join_path(d, prefix + random_number(mut rng) + suffix)
|
||||
os.mkdir_all(path) or {
|
||||
rng.seed(rutil.time_seed_array(2))
|
||||
rng.seed(rseed.time_seed_array(2))
|
||||
continue
|
||||
}
|
||||
if os.is_dir(path) && os.exists(path) {
|
||||
@ -96,9 +92,7 @@ fn prefix_and_suffix(pattern string) ?(string, string) {
|
||||
if pat.contains(os.path_separator) {
|
||||
return error('pattern cannot contain path separators ($os.path_separator).')
|
||||
}
|
||||
pos := pat.last_index('*') or {
|
||||
-1
|
||||
}
|
||||
pos := pat.last_index('*') or { -1 }
|
||||
mut prefix := ''
|
||||
mut suffix := ''
|
||||
if pos != -1 {
|
||||
|
@ -4,7 +4,7 @@
|
||||
module mt19937
|
||||
|
||||
import math.bits
|
||||
import rand.util
|
||||
import rand.seed
|
||||
|
||||
/*
|
||||
C++ functions for MT19937, with initialization improved 2002/2/10.
|
||||
@ -59,8 +59,8 @@ const (
|
||||
// MT19937RNG is generator that uses the Mersenne Twister algorithm with period 2^19937.
|
||||
pub struct MT19937RNG {
|
||||
mut:
|
||||
state []u64 = calculate_state(util.time_seed_array(2), mut []u64{len: nn})
|
||||
mti int = nn
|
||||
state []u64 = calculate_state(seed.time_seed_array(2), mut []u64{len: mt19937.nn})
|
||||
mti int = mt19937.nn
|
||||
next_rnd u32
|
||||
has_next bool
|
||||
}
|
||||
@ -70,7 +70,7 @@ fn calculate_state(seed_data []u32, mut state []u64) []u64 {
|
||||
lo := u64(seed_data[0])
|
||||
hi := u64(seed_data[1])
|
||||
state[0] = u64((hi << 32) | lo)
|
||||
for j := 1; j < nn; j++ {
|
||||
for j := 1; j < mt19937.nn; j++ {
|
||||
state[j] = u64(6364136223846793005) * (state[j - 1] ^ (state[j - 1] >> 62)) + u64(j)
|
||||
}
|
||||
return *state
|
||||
@ -84,7 +84,7 @@ pub fn (mut rng MT19937RNG) seed(seed_data []u32) {
|
||||
exit(1)
|
||||
}
|
||||
rng.state = calculate_state(seed_data, mut rng.state)
|
||||
rng.mti = nn
|
||||
rng.mti = mt19937.nn
|
||||
rng.next_rnd = 0
|
||||
rng.has_next = false
|
||||
}
|
||||
@ -105,21 +105,21 @@ pub fn (mut rng MT19937RNG) u32() u32 {
|
||||
// u64 returns a pseudorandom 64bit int in range `[0, 2⁶⁴)`.
|
||||
[inline]
|
||||
pub fn (mut rng MT19937RNG) u64() u64 {
|
||||
mag01 := [u64(0), u64(matrix_a)]
|
||||
mag01 := [u64(0), u64(mt19937.matrix_a)]
|
||||
mut x := u64(0)
|
||||
mut i := int(0)
|
||||
if rng.mti >= nn {
|
||||
for i = 0; i < nn - mm; i++ {
|
||||
x = (rng.state[i] & um) | (rng.state[i + 1] & lm)
|
||||
rng.state[i] = rng.state[i + mm] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
if rng.mti >= mt19937.nn {
|
||||
for i = 0; i < mt19937.nn - mt19937.mm; i++ {
|
||||
x = (rng.state[i] & mt19937.um) | (rng.state[i + 1] & mt19937.lm)
|
||||
rng.state[i] = rng.state[i + mt19937.mm] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
}
|
||||
for i < nn - 1 {
|
||||
x = (rng.state[i] & um) | (rng.state[i + 1] & lm)
|
||||
rng.state[i] = rng.state[i + (mm - nn)] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
for i < mt19937.nn - 1 {
|
||||
x = (rng.state[i] & mt19937.um) | (rng.state[i + 1] & mt19937.lm)
|
||||
rng.state[i] = rng.state[i + (mt19937.mm - mt19937.nn)] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
i++
|
||||
}
|
||||
x = (rng.state[nn - 1] & um) | (rng.state[0] & lm)
|
||||
rng.state[nn - 1] = rng.state[mm - 1] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
x = (rng.state[mt19937.nn - 1] & mt19937.um) | (rng.state[0] & mt19937.lm)
|
||||
rng.state[mt19937.nn - 1] = rng.state[mt19937.mm - 1] ^ (x >> 1) ^ mag01[int(x & 1)]
|
||||
rng.mti = 0
|
||||
}
|
||||
x = rng.state[rng.mti]
|
||||
@ -279,7 +279,7 @@ pub fn (mut rng MT19937RNG) f32() f32 {
|
||||
// f64 returns 64bit real (`f64`) in range `[0, 1)`.
|
||||
[inline]
|
||||
pub fn (mut rng MT19937RNG) f64() f64 {
|
||||
return f64(rng.u64() >> 11) * inv_f64_limit
|
||||
return f64(rng.u64() >> 11) * mt19937.inv_f64_limit
|
||||
}
|
||||
|
||||
// f32n returns a 32bit real (`f32`) in range [0, max)`.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import math
|
||||
import rand.mt19937
|
||||
import rand.util
|
||||
import rand.seed
|
||||
|
||||
const (
|
||||
range_limit = 40
|
||||
@ -26,7 +26,7 @@ fn mt19937_basic_test() {
|
||||
|
||||
fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
bound_u64 := u64(bound)
|
||||
mut randoms := []u64{len:(20)}
|
||||
mut randoms := []u64{len: (20)}
|
||||
mut rnd := mt19937.MT19937RNG{}
|
||||
rnd.seed(seed_data)
|
||||
for i in 0 .. 20 {
|
||||
@ -36,7 +36,7 @@ fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
}
|
||||
|
||||
fn test_mt19937_reproducibility() {
|
||||
seed_data := util.time_seed_array(2)
|
||||
seed_data := seed.time_seed_array(2)
|
||||
randoms1 := gen_randoms(seed_data, 1000)
|
||||
randoms2 := gen_randoms(seed_data, 1000)
|
||||
assert randoms1.len == randoms2.len
|
||||
|
@ -4,12 +4,13 @@
|
||||
module musl
|
||||
|
||||
import math.bits
|
||||
import rand.seed
|
||||
import rand.util
|
||||
|
||||
// MuslRNG ported from https://git.musl-libc.org/cgit/musl/tree/src/prng/rand_r.c
|
||||
pub struct MuslRNG {
|
||||
mut:
|
||||
state u32 = util.time_seed_32()
|
||||
state u32 = seed.time_seed_32()
|
||||
}
|
||||
|
||||
// seed sets the current random state based on `seed_data`.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import math
|
||||
import rand.musl
|
||||
import rand.util
|
||||
import rand.seed
|
||||
|
||||
const (
|
||||
range_limit = 40
|
||||
@ -16,7 +16,7 @@ const (
|
||||
|
||||
fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
bound_u64 := u64(bound)
|
||||
mut randoms := []u64{len:(20)}
|
||||
mut randoms := []u64{len: (20)}
|
||||
mut rnd := musl.MuslRNG{}
|
||||
rnd.seed(seed_data)
|
||||
for i in 0 .. 20 {
|
||||
@ -26,7 +26,7 @@ fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
}
|
||||
|
||||
fn test_musl_reproducibility() {
|
||||
seed_data := util.time_seed_array(1)
|
||||
seed_data := seed.time_seed_array(1)
|
||||
randoms1 := gen_randoms(seed_data, 1000)
|
||||
randoms2 := gen_randoms(seed_data, 1000)
|
||||
assert randoms1.len == randoms2.len
|
||||
|
@ -3,6 +3,7 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module pcg32
|
||||
|
||||
import rand.seed
|
||||
import rand.util
|
||||
|
||||
// PCG32RNG ported from http://www.pcg-random.org/download.html,
|
||||
@ -10,8 +11,8 @@ import rand.util
|
||||
// https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.h
|
||||
pub struct PCG32RNG {
|
||||
mut:
|
||||
state u64 = u64(0x853c49e6748fea9b) ^ util.time_seed_64()
|
||||
inc u64 = u64(0xda3e39cb94b95bdb) ^ util.time_seed_64()
|
||||
state u64 = u64(0x853c49e6748fea9b) ^ seed.time_seed_64()
|
||||
inc u64 = u64(0xda3e39cb94b95bdb) ^ seed.time_seed_64()
|
||||
}
|
||||
|
||||
// seed seeds the PCG32RNG with 4 `u32` values.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import math
|
||||
import rand.pcg32
|
||||
import rand.util
|
||||
import rand.seed
|
||||
|
||||
const (
|
||||
range_limit = 40
|
||||
@ -25,7 +25,7 @@ fn gen_randoms(seed_data []u32, bound int) []u32 {
|
||||
}
|
||||
|
||||
fn test_pcg32_reproducibility() {
|
||||
seed_data := util.time_seed_array(4)
|
||||
seed_data := seed.time_seed_array(4)
|
||||
randoms1 := gen_randoms(seed_data, 1000)
|
||||
randoms2 := gen_randoms(seed_data, 1000)
|
||||
assert randoms1.len == randoms2.len
|
||||
|
@ -3,13 +3,13 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module rand
|
||||
|
||||
import rand.util
|
||||
import rand.seed
|
||||
import rand.wyrand
|
||||
import time
|
||||
|
||||
// PRNGConfigStruct is a configuration struct for creating a new instance of the default RNG.
|
||||
pub struct PRNGConfigStruct {
|
||||
seed []u32 = util.time_seed_array(2)
|
||||
seed []u32 = seed.time_seed_array(2)
|
||||
}
|
||||
|
||||
__global ( default_rng &wyrand.WyRandRNG )
|
||||
@ -141,10 +141,10 @@ pub fn string(len int) string {
|
||||
mut buf := malloc(len)
|
||||
for i in 0 .. len {
|
||||
unsafe {
|
||||
buf[i] = chars[intn(chars.len)]
|
||||
buf[i] = rand.chars[intn(rand.chars.len)]
|
||||
}
|
||||
}
|
||||
return unsafe {buf.vstring_with_len(len)}
|
||||
return unsafe { buf.vstring_with_len(len) }
|
||||
}
|
||||
|
||||
// uuid_v4 generates a random (v4) UUID
|
||||
@ -184,7 +184,7 @@ pub fn uuid_v4() string {
|
||||
buf[14] = `4`
|
||||
buf[buflen] = 0
|
||||
}
|
||||
return unsafe {buf.vstring_with_len(buflen)}
|
||||
return unsafe { buf.vstring_with_len(buflen) }
|
||||
}
|
||||
|
||||
const (
|
||||
@ -209,7 +209,7 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
|
||||
mut i := 9
|
||||
for i >= 0 {
|
||||
unsafe {
|
||||
buf[i] = ulid_encoding[t & 0x1F]
|
||||
buf[i] = rand.ulid_encoding[t & 0x1F]
|
||||
}
|
||||
t = t >> 5
|
||||
i--
|
||||
@ -219,7 +219,7 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
|
||||
i = 10
|
||||
for i < 19 {
|
||||
unsafe {
|
||||
buf[i] = ulid_encoding[x & 0x1F]
|
||||
buf[i] = rand.ulid_encoding[x & 0x1F]
|
||||
}
|
||||
x = x >> 5
|
||||
i++
|
||||
@ -228,7 +228,7 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
|
||||
x = default_rng.u64()
|
||||
for i < 26 {
|
||||
unsafe {
|
||||
buf[i] = ulid_encoding[x & 0x1F]
|
||||
buf[i] = rand.ulid_encoding[x & 0x1F]
|
||||
}
|
||||
x = x >> 5
|
||||
i++
|
||||
@ -236,5 +236,5 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
|
||||
unsafe {
|
||||
buf[26] = 0
|
||||
}
|
||||
return unsafe {buf.vstring_with_len(buflen)}
|
||||
return unsafe { buf.vstring_with_len(buflen) }
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn test_ulids_generated_in_the_same_millisecond_have_the_same_prefix() {
|
||||
t := time.utc().unix_time_milli()
|
||||
mut ulid1 := ''
|
||||
mut ulid2 := ''
|
||||
mut ulid3 := ''
|
||||
mut ulid3 := ''
|
||||
ulid1 = rand.ulid_at_millisecond(t)
|
||||
ulid2 = rand.ulid_at_millisecond(t)
|
||||
ulid3 = rand.ulid_at_millisecond(t)
|
||||
|
40
vlib/rand/seed/seed.v
Normal file
40
vlib/rand/seed/seed.v
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module seed
|
||||
|
||||
import time
|
||||
|
||||
// nr_next returns a next value based on the previous value `prev`.
|
||||
[inline]
|
||||
fn nr_next(prev u32) u32 {
|
||||
return prev * 1664525 + 1013904223
|
||||
}
|
||||
|
||||
// time_seed_array returns the required number of u32s generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_array(count int) []u32 {
|
||||
ctime := time.now()
|
||||
mut seed := u32(ctime.unix_time() ^ ctime.microsecond)
|
||||
mut seed_data := []u32{cap: count}
|
||||
for _ in 0 .. count {
|
||||
seed = nr_next(seed)
|
||||
seed_data << nr_next(seed)
|
||||
}
|
||||
return seed_data
|
||||
}
|
||||
|
||||
// time_seed_32 returns a 32-bit seed generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_32() u32 {
|
||||
return time_seed_array(1)[0]
|
||||
}
|
||||
|
||||
// time_seed_64 returns a 64-bit seed generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_64() u64 {
|
||||
seed_data := time_seed_array(2)
|
||||
lower := u64(seed_data[0])
|
||||
upper := u64(seed_data[1])
|
||||
return lower | (upper << 32)
|
||||
}
|
@ -3,12 +3,13 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module splitmix64
|
||||
|
||||
import rand.seed
|
||||
import rand.util
|
||||
|
||||
// SplitMix64RNG ported from http://xoshiro.di.unimi.it/splitmix64.c
|
||||
pub struct SplitMix64RNG {
|
||||
mut:
|
||||
state u64 = util.time_seed_64()
|
||||
state u64 = seed.time_seed_64()
|
||||
has_extra bool
|
||||
extra u32
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import math
|
||||
import rand.splitmix64
|
||||
import rand.util
|
||||
import rand.seed
|
||||
|
||||
const (
|
||||
range_limit = 40
|
||||
@ -16,7 +16,7 @@ const (
|
||||
|
||||
fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
bound_u64 := u64(bound)
|
||||
mut randoms := []u64{len:(20)}
|
||||
mut randoms := []u64{len: (20)}
|
||||
mut rnd := splitmix64.SplitMix64RNG{}
|
||||
rnd.seed(seed_data)
|
||||
for i in 0 .. 20 {
|
||||
@ -26,7 +26,7 @@ fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
}
|
||||
|
||||
fn test_splitmix64_reproducibility() {
|
||||
seed_data := util.time_seed_array(2)
|
||||
seed_data := seed.time_seed_array(2)
|
||||
randoms1 := gen_randoms(seed_data, 1000)
|
||||
randoms2 := gen_randoms(seed_data, 1000)
|
||||
assert randoms1.len == randoms2.len
|
||||
|
@ -4,6 +4,7 @@
|
||||
module sys
|
||||
|
||||
import math.bits
|
||||
import rand.seed
|
||||
import rand.util
|
||||
|
||||
// Implementation note:
|
||||
@ -23,8 +24,8 @@ const (
|
||||
)
|
||||
|
||||
fn calculate_iterations_for(bits int) int {
|
||||
base := bits / rand_bitsize
|
||||
extra := if bits % rand_bitsize == 0 { 0 } else { 1 }
|
||||
base := bits / sys.rand_bitsize
|
||||
extra := if bits % sys.rand_bitsize == 0 { 0 } else { 1 }
|
||||
return base + extra
|
||||
}
|
||||
|
||||
@ -36,7 +37,7 @@ fn C.rand() int
|
||||
// SysRNG is the PRNG provided by default in the libc implementiation that V uses.
|
||||
pub struct SysRNG {
|
||||
mut:
|
||||
seed u32 = util.time_seed_32()
|
||||
seed u32 = seed.time_seed_32()
|
||||
}
|
||||
|
||||
// r.seed() sets the seed of the accepting SysRNG to the given data.
|
||||
@ -46,7 +47,7 @@ pub fn (mut r SysRNG) seed(seed_data []u32) {
|
||||
exit(1)
|
||||
}
|
||||
r.seed = seed_data[0]
|
||||
unsafe {C.srand(int(r.seed))}
|
||||
unsafe { C.srand(int(r.seed)) }
|
||||
}
|
||||
|
||||
// r.default_rand() exposes the default behavior of the system's RNG
|
||||
@ -63,8 +64,8 @@ pub fn (r SysRNG) default_rand() int {
|
||||
[inline]
|
||||
pub fn (r SysRNG) u32() u32 {
|
||||
mut result := u32(C.rand())
|
||||
for i in 1 .. u32_iter_count {
|
||||
result = result ^ (u32(C.rand()) << (rand_bitsize * i))
|
||||
for i in 1 .. sys.u32_iter_count {
|
||||
result = result ^ (u32(C.rand()) << (sys.rand_bitsize * i))
|
||||
}
|
||||
return result
|
||||
}
|
||||
@ -73,8 +74,8 @@ pub fn (r SysRNG) u32() u32 {
|
||||
[inline]
|
||||
pub fn (r SysRNG) u64() u64 {
|
||||
mut result := u64(C.rand())
|
||||
for i in 1 .. u64_iter_count {
|
||||
result = result ^ (u64(C.rand()) << (rand_bitsize * i))
|
||||
for i in 1 .. sys.u64_iter_count {
|
||||
result = result ^ (u64(C.rand()) << (sys.rand_bitsize * i))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module util
|
||||
|
||||
import time
|
||||
|
||||
// Commonly used constants across RNGs - some taken from "Numerical Recipes".
|
||||
pub const (
|
||||
lower_mask = u64(0x00000000FFFFFFFF)
|
||||
@ -15,37 +13,3 @@ pub const (
|
||||
u31_mask = u32(0x7FFFFFFF)
|
||||
u63_mask = u64(0x7FFFFFFFFFFFFFFF)
|
||||
)
|
||||
|
||||
// nr_next returns a next value based on the previous value `prev`.
|
||||
[inline]
|
||||
fn nr_next(prev u32) u32 {
|
||||
return prev * 1664525 + 1013904223
|
||||
}
|
||||
|
||||
// time_seed_array returns the required number of u32s generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_array(count int) []u32 {
|
||||
ctime := time.now()
|
||||
mut seed := u32(ctime.unix_time() ^ ctime.microsecond)
|
||||
mut seed_data := []u32{cap: count}
|
||||
for _ in 0 .. count {
|
||||
seed = nr_next(seed)
|
||||
seed_data << nr_next(seed)
|
||||
}
|
||||
return seed_data
|
||||
}
|
||||
|
||||
// time_seed_32 returns a 32-bit seed generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_32() u32 {
|
||||
return time_seed_array(1)[0]
|
||||
}
|
||||
|
||||
// time_seed_64 returns a 64-bit seed generated from system time.
|
||||
[inline]
|
||||
pub fn time_seed_64() u64 {
|
||||
seed_data := time_seed_array(2)
|
||||
lower := u64(seed_data[0])
|
||||
upper := u64(seed_data[1])
|
||||
return lower | (upper << 32)
|
||||
}
|
||||
|
@ -4,8 +4,9 @@
|
||||
module wyrand
|
||||
|
||||
import math.bits
|
||||
import rand.seed
|
||||
import rand.util
|
||||
import hash as wyhash
|
||||
import hash
|
||||
|
||||
// Redefinition of some constants that we will need for pseudorandom number generation.
|
||||
const (
|
||||
@ -16,7 +17,7 @@ const (
|
||||
// WyRandRNG is a RNG based on the WyHash hashing algorithm.
|
||||
pub struct WyRandRNG {
|
||||
mut:
|
||||
state u64 = util.time_seed_64()
|
||||
state u64 = seed.time_seed_64()
|
||||
has_extra bool
|
||||
extra u32
|
||||
}
|
||||
@ -51,9 +52,9 @@ pub fn (mut rng WyRandRNG) u32() u32 {
|
||||
pub fn (mut rng WyRandRNG) u64() u64 {
|
||||
unsafe {
|
||||
mut seed1 := rng.state
|
||||
seed1 += wyp0
|
||||
seed1 += wyrand.wyp0
|
||||
rng.state = seed1
|
||||
return wyhash.wymum(seed1 ^ wyp1, seed1)
|
||||
return hash.wymum(seed1 ^ wyrand.wyp1, seed1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import math
|
||||
import rand.util
|
||||
import rand.seed
|
||||
import rand.wyrand
|
||||
|
||||
const (
|
||||
@ -16,7 +16,7 @@ const (
|
||||
|
||||
fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
bound_u64 := u64(bound)
|
||||
mut randoms := []u64{len:(20)}
|
||||
mut randoms := []u64{len: (20)}
|
||||
mut rnd := wyrand.WyRandRNG{}
|
||||
rnd.seed(seed_data)
|
||||
for i in 0 .. 20 {
|
||||
@ -26,7 +26,7 @@ fn gen_randoms(seed_data []u32, bound int) []u64 {
|
||||
}
|
||||
|
||||
fn test_wyrand_reproducibility() {
|
||||
seed_data := util.time_seed_array(2)
|
||||
seed_data := seed.time_seed_array(2)
|
||||
randoms1 := gen_randoms(seed_data, 1000)
|
||||
randoms2 := gen_randoms(seed_data, 1000)
|
||||
assert randoms1.len == randoms2.len
|
||||
|
Loading…
Reference in New Issue
Block a user