diff --git a/Project.toml b/Project.toml index 2286e8d7..b2d86cc5 100644 --- a/Project.toml +++ b/Project.toml @@ -3,13 +3,16 @@ uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.5" [deps] +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] +StableRNGs = "1" julia = "1" [extras] +StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["StableRNGs", "Test"] diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 7e4ab7d3..ec9e991f 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -7,9 +7,10 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox, big, rationalize, float, trunc, round, floor, ceil, bswap, clamp, div, fld, rem, mod, mod1, fld1, min, max, minmax, signed, unsigned, copysign, flipsign, signbit, - rand, length + length import Statistics # for _mean_promote +import Random: Random, AbstractRNG, SamplerType, rand! using Base.Checked: checked_add, checked_sub, checked_div @@ -326,8 +327,15 @@ scaledual(::Type{Tdual}, x::AbstractArray{T}) where {Tdual, T <: FixedPoint} = throw(ArgumentError("$X is $bitstring type representing $n values from $Xmin to $Xmax; cannot represent $x")) end -rand(::Type{T}) where {T <: FixedPoint} = reinterpret(T, rand(rawtype(T))) -rand(::Type{T}, sz::Dims) where {T <: FixedPoint} = reinterpret(T, rand(rawtype(T), sz)) +function Random.rand(r::AbstractRNG, ::SamplerType{X}) where X <: FixedPoint + X(rand(r, rawtype(X)), 0) +end + +function rand!(r::AbstractRNG, A::Array{X}, ::SamplerType{X}) where {T, X <: FixedPoint{T}} + At = unsafe_wrap(Array, reinterpret(Ptr{T}, pointer(A)), size(A)) + Random.rand!(r, At, SamplerType{T}()) + A +end if VERSION >= v"1.1" # work around https://github.com/JuliaLang/julia/issues/34121 include("precompile.jl") diff --git a/src/precompile.jl b/src/precompile.jl index 178be83f..5d485d3e 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -1,3 +1,5 @@ +using Random + function _precompile_() ccall(:jl_generating_output, Cint, ()) == 1 || return nothing normedtypes = (N0f8, N0f16) # precompiled Normed types diff --git a/test/fixed.jl b/test/fixed.jl index 459f8eda..f96f7c76 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -1,4 +1,4 @@ -using FixedPointNumbers, Statistics, Test +using FixedPointNumbers, Statistics, Random, StableRNGs, Test using FixedPointNumbers: bitwidth # issue #288 @@ -404,6 +404,8 @@ end @test ndims(a) == 2 && eltype(a) == F @test size(a) == (3,5) end + @test !(rand(Q0f15) == rand(Q0f15) == rand(Q0f15)) # If this fails, we should suspect a bug. + @test rand(StableRNG(1234), Q0f7) === 0.531Q0f7 end @testset "floatmin" begin diff --git a/test/normed.jl b/test/normed.jl index d24eb541..a2032d61 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -1,4 +1,4 @@ -using FixedPointNumbers, Statistics, Test +using FixedPointNumbers, Statistics, Random, StableRNGs, Test using FixedPointNumbers: bitwidth # issue #288 @@ -595,6 +595,8 @@ end @test ndims(a) == 2 && eltype(a) == T @test size(a) == (3,5) end + @test !(rand(N0f16) == rand(N0f16) == rand(N0f16)) # If this fails, we should suspect a bug. + @test rand(StableRNG(1234), N0f8) === 0.267N0f8 end @testset "Overflow with Float16" begin