From 3970d79bbc7fa32695df452f3791b81703371b8a Mon Sep 17 00:00:00 2001 From: sunoru Date: Sun, 30 Sep 2018 15:10:18 -0400 Subject: [PATCH] Raise an error when `seed!` Xorshifts RNGs with 0. Fix #48. --- docs/src/man/xorshifts.md | 2 +- src/Xorshifts/docs.jl | 8 ++++---- src/Xorshifts/xoroshiro128.jl | 1 + src/Xorshifts/xorshift1024.jl | 1 + src/Xorshifts/xorshift128.jl | 1 + src/Xorshifts/xorshift64.jl | 1 + test/Xorshifts/runtests.jl | 5 +++++ test/common.jl | 2 +- 8 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/src/man/xorshifts.md b/docs/src/man/xorshifts.md index 2e0282d..94da8e8 100644 --- a/docs/src/man/xorshifts.md +++ b/docs/src/man/xorshifts.md @@ -42,7 +42,7 @@ julia> using RandomNumbers.Xorshifts julia> r = Xoroshiro128Plus(); # create a RNG with truly random seed. -julia> r = Xoroshiro128Plus(0x1234567890abcdef) # with a certain seed. +julia> r = Xoroshiro128Plus(0x1234567890abcdef) # with a certain seed. Note that the seed must be non-zero. RandomNumbers.Xorshifts.Xoroshiro128Plus(0x13c5b80b0f92f3ac, 0xcdd3f80fa9fb6887) julia> rand(r) diff --git a/src/Xorshifts/docs.jl b/src/Xorshifts/docs.jl index 2bf7f00..5f2f9df 100644 --- a/src/Xorshifts/docs.jl +++ b/src/Xorshifts/docs.jl @@ -9,7 +9,7 @@ $r <: AbstractXorshift64 $r([seed]) ``` -$r RNG. The `seed` will be automatically convert to an `UInt64` number. +$r RNG. The `seed` will be automatically convert to an `UInt64` number. A zero seed is not acceptable. """ @doc doc_xorshift64("Xorshift64") Xorshift64 @doc doc_xorshift64("Xorshift64Star") Xorshift64Star @@ -22,7 +22,7 @@ $r([seed]) ``` $r RNG. The `seed` can be a `Tuple` of two `UInt64`s, or an `Integer` which will be automatically convert to -an `UInt128` number. +an `UInt128` number. Zero seeds are not acceptable. """ @doc doc_xorshift128("Xorshift128") Xorshift128 @doc doc_xorshift128("Xorshift128Star") Xorshift128Star @@ -36,7 +36,7 @@ $r([seed...]) ``` $r RNG. The `seed` can be a `Tuple` of 16 `UInt64`s, or several (no more than 16) `Integer`s which will all -be automatically converted to `UInt64` numbers. +be automatically converted to `UInt64` numbers. Zero seeds are not acceptable. """ @doc doc_xorshift1024("Xorshift1024") Xorshift1024 @doc doc_xorshift1024("Xorshift1024Star") Xorshift1024Star @@ -50,7 +50,7 @@ $r([seed]) ``` $r RNG. The `seed` can be a `Tuple` of two `UInt64`s, or an `Integer` which will be automatically convert to -an `UInt128` number. +an `UInt128` number. Zero seeds are not acceptable. """ @doc doc_xoroshiro128("Xoroshiro128") Xoroshiro128 @doc doc_xoroshiro128("Xoroshiro128Star") Xoroshiro128Star diff --git a/src/Xorshifts/xoroshiro128.jl b/src/Xorshifts/xoroshiro128.jl index 16def30..fbabb49 100644 --- a/src/Xorshifts/xoroshiro128.jl +++ b/src/Xorshifts/xoroshiro128.jl @@ -57,6 +57,7 @@ copy(src::T) where T <: AbstractXoroshiro128 = copyto!(T(), src) seed!(r::AbstractXoroshiro128, seed::Integer) = seed!(r, split_uint(seed % UInt128)) function seed!(r::AbstractXoroshiro128, seed::NTuple{2, UInt64}=gen_seed(UInt64, 2)) + all(==(0), seed) && error("0 cannot be the seed") r.x = seed[1] r.y = seed[2] xorshift_next(r) diff --git a/src/Xorshifts/xorshift1024.jl b/src/Xorshifts/xorshift1024.jl index dd09566..cb7fd8b 100644 --- a/src/Xorshifts/xorshift1024.jl +++ b/src/Xorshifts/xorshift1024.jl @@ -84,6 +84,7 @@ copy(src::T) where T <: AbstractXorshift1024 = copyto!(T(), src) ==(r1::T, r2::T) where T <: AbstractXorshift1024 = unsafe_compare(r1, r2, UInt64, 16) && r1.p == r2.p function seed!(r::AbstractXorshift1024, seed::NTuple{16, UInt64}) + all(==(0), seed) && error("0 cannot be the seed") ptr = Ptr{UInt64}(pointer_from_objref(r)) @inbounds for i in 1:16 unsafe_store!(ptr, seed[i], i) diff --git a/src/Xorshifts/xorshift128.jl b/src/Xorshifts/xorshift128.jl index ef2c585..f579589 100644 --- a/src/Xorshifts/xorshift128.jl +++ b/src/Xorshifts/xorshift128.jl @@ -55,6 +55,7 @@ copy(src::T) where T <: AbstractXorshift128 = copyto!(T(), src) seed!(r::AbstractXorshift128, seed::Integer) = seed!(r, split_uint(seed % UInt128)) function seed!(r::AbstractXorshift128, seed::NTuple{2, UInt64}=gen_seed(UInt64, 2)) + all(==(0), seed) && error("0 cannot be the seed") r.x = seed[1] r.y = seed[2] xorshift_next(r) diff --git a/src/Xorshifts/xorshift64.jl b/src/Xorshifts/xorshift64.jl index 6c5d8c4..a1206db 100644 --- a/src/Xorshifts/xorshift64.jl +++ b/src/Xorshifts/xorshift64.jl @@ -46,6 +46,7 @@ copy(src::T) where T <: AbstractXorshift64 = copyto!(T(), src) ==(r1::T, r2::T) where T <: AbstractXorshift64 = r1.x == r2.x function seed!(r::AbstractXorshift64, seed::Integer=gen_seed(UInt64)) + seed == 0 && error("0 cannot be the seed") r.x = seed % UInt64 xorshift_next(r) r diff --git a/test/Xorshifts/runtests.jl b/test/Xorshifts/runtests.jl index f168e3a..c585724 100644 --- a/test/Xorshifts/runtests.jl +++ b/test/Xorshifts/runtests.jl @@ -36,6 +36,10 @@ for (rng_name, seed_t) in ( redirect_stdout(outfile) @eval x = $rng_name() + @test_throws( + ErrorException("0 cannot be the seed"), + seed_t === NTuple{16, UInt64} ? seed!(x, zeros(UInt64, 16)...) : seed!(x, 0) + ) seed!(x) @test seed_type(x) == seed_t @test copyto!(copy(x), x) == x @@ -54,5 +58,6 @@ for (rng_name, seed_t) in ( end redirect_stdout(stdout_) + compare_dirs("expected", "actual") cd(pwd_) diff --git a/test/common.jl b/test/common.jl index c71aa12..728abd2 100644 --- a/test/common.jl +++ b/test/common.jl @@ -1,6 +1,6 @@ using RandomNumbers import Random: seed! -using Test: @test +using Test: @test, @test_throws using Base.Printf: @printf function compare_dirs(dir1::AbstractString, dir2::AbstractString)