From 7c2e68bfb158517c8cf6437751a93a0e6e034610 Mon Sep 17 00:00:00 2001 From: kimikage Date: Fri, 3 Jan 2020 01:41:20 +0900 Subject: [PATCH] Add depwarn in constructor of Fixed{T,f} where f == 8sizeof(T) This also adds the domain checks for `f` in the constructors. --- src/fixed.jl | 8 +++++++- src/normed.jl | 5 ++++- test/fixed.jl | 28 ++++++++++++++++++---------- test/normed.jl | 7 +++++++ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/fixed.jl b/src/fixed.jl index d4164b67..67711f89 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -15,7 +15,13 @@ struct Fixed{T <: Signed, f} <: FixedPoint{T, f} # constructor for manipulating the representation; # selected by passing an extra dummy argument - Fixed{T, f}(i::Integer, _) where {T,f} = new{T, f}(i % T) + function Fixed{T, f}(i::Integer, _) where {T, f} + if f == bitwidth(T) + Base.depwarn("`Fixed` reserves one bit for the sign. Support for `f=$f` with raw type `T=$T` will be removed in a future release.", :Fixed) + end + 0 <= f <= bitwidth(T) || throw(DomainError(f, "f must be between 0 and $(bitwidth(T)-1) (i.e. the number of non-sign bits of `T=$T`)")) # TODO: change the upper limit + new{T, f}(i % T) + end end Fixed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Fixed cannot be constructed from a Char")) diff --git a/src/normed.jl b/src/normed.jl index 7e119bba..8112d9b8 100644 --- a/src/normed.jl +++ b/src/normed.jl @@ -13,7 +13,10 @@ underlying bits used. For example, `N0f8` is aliased to `Normed{UInt8,8}` and struct Normed{T <: Unsigned, f} <: FixedPoint{T, f} i::T - Normed{T, f}(i::Integer,_) where {T,f} = new{T, f}(i%T) # for setting by raw representation + function Normed{T, f}(i::Integer, _) where {T, f} + 1 <= f <= bitwidth(T) || throw(DomainError(f, "f must be between 1 and $(bitwidth(T)) (i.e. the number of bits of `T=$T`)")) + new{T, f}(i % T) + end end Normed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Normed cannot be constructed from a Char")) diff --git a/test/fixed.jl b/test/fixed.jl index 96f7cc6a..21a8a930 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -50,6 +50,16 @@ function test_fixed(::Type{T}, f) where {T} end end +@testset "domain of f" begin + # TODO: change the upper limit + @test_logs (:warn, r"`f=8` with raw type `T=Int8` will be removed") zero(Fixed{Int8,8}) + @test_throws DomainError zero(Fixed{Int8,-1}) + # @test_throws DomainError zero(Fixed{Int8,8}) + @test_throws DomainError zero(Fixed{Int8,9}) + # @test_throws DomainError zero(Fixed{Int16,16}) + @test_throws DomainError zero(Fixed{Int16,17}) +end + @testset "reinterpret" begin @test reinterpret(Q0f7, signed(0xa2)) === -0.734375Q0f7 @test reinterpret(Q5f10, signed(0x00a2)) === 0.158203125Q5f10 @@ -65,7 +75,7 @@ end # TODO: change back to InexactError when it allows message strings @test_throws ArgumentError one(Q0f15) @test_throws ArgumentError oneunit(Q0f31) - @test_throws ArgumentError one(Fixed{Int8,8}) + @test_throws ArgumentError one(Fixed{Int8,8}) # TODO: remove this at end of its support end @testset "conversion" begin @@ -79,7 +89,7 @@ end end @testset "test_fixed" begin - for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] + for (TI, f) in [(Int8, 7), (Int16, 8), (Int16, 10), (Int32, 16)] T = Fixed{TI,f} # println(" Testing $T") test_fixed(T, f) @@ -112,8 +122,7 @@ end end @testset "reductions" begin - F8 = Fixed{Int8,8} - a = F8[0.498, 0.1] + a = Q0f7[0.75, 0.5] acmp = Float64(a[1]) + Float64(a[2]) @test sum(a) == acmp @test sum(a, dims=1) == [acmp] @@ -126,7 +135,7 @@ end end @testset "convert result type" begin - x = Fixed{Int8,8}(0.3) + x = Fixed{Int8,7}(0.75) for T in (Float16, Float32, Float64, BigFloat) y = convert(T, x) @test isa(y, T) @@ -154,11 +163,10 @@ end end @testset "rand" begin - for T in (Fixed{Int8,8}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) - a = rand(T) - @test isa(a, T) - a = rand(T, (3, 5)) - @test ndims(a) == 2 && eltype(a) == T + for F in (Fixed{Int8,7}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) + @test isa(rand(F), F) + a = rand(F, (3, 5)) + @test ndims(a) == 2 && eltype(a) == F @test size(a) == (3,5) end end diff --git a/test/normed.jl b/test/normed.jl index 4c0430ea..31d49060 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -1,6 +1,13 @@ using FixedPointNumbers, Test using FixedPointNumbers: bitwidth +@testset "domain of f" begin + @test_throws DomainError zero(Normed{UInt8,-1}) + @test_throws DomainError zero(Normed{UInt8,0}) + @test_throws DomainError zero(Normed{UInt8,9}) + @test_throws DomainError zero(Normed{UInt16,17}) +end + @testset "reinterpret" begin @test reinterpret(N0f8, 0xa2).i === 0xa2 @test reinterpret(N6f10, 0x1fa2).i === 0x1fa2