From 5cf20d51c5e1a2ca700c6399c1278a4e4af94f6a Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Wed, 15 May 2019 15:12:23 +0800 Subject: [PATCH 1/9] fix isinteger fixes #120 : `isinteger(1N0f8)` should be true --- src/normed.jl | 3 +++ test/fixed.jl | 8 ++++++++ test/normed.jl | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/src/normed.jl b/src/normed.jl index 6a4faed2..67b87e3a 100644 --- a/src/normed.jl +++ b/src/normed.jl @@ -169,3 +169,6 @@ end _unsafe_trunc(::Type{T}, x::Integer) where {T} = x % T _unsafe_trunc(::Type{T}, x) where {T} = unsafe_trunc(T, x) + +# predicates +isinteger(x::Normed{T,f}) where {T,f} = (x.i%(1< Date: Wed, 15 May 2019 20:29:57 +0800 Subject: [PATCH 2/9] temp fix --- test/fixed.jl | 4 ++-- test/normed.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/fixed.jl b/test/fixed.jl index 8d2e63ac..164047c3 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -149,8 +149,8 @@ end @testset "isinteger" begin # issue #120 for T in (Fixed{Int8,6}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) - a = 1 - @test all(isinteger.(T.(a))) + T_ints = round.(clamp.(rand(Int, 50, 50), typemin(T), typemax(T))) + @test all(isinteger.(T.(T_ints))) end end diff --git a/test/normed.jl b/test/normed.jl index 6721bb89..7b18efde 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -348,7 +348,7 @@ end @testset "isinteger" begin # issue #120 for T in (Normed{UInt8,6}, Normed{UInt16,8}, Normed{UInt16,10}, Normed{UInt32,16}) - a = 1 + a = round.(clamp.(rand(Int, 50, 50), typemin(T), typemax(T))) @test all(isinteger.(T.(a))) end end From 4bcc60ce0bf9de187e11aa687924182a49b8e489 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Wed, 15 May 2019 19:43:10 +0800 Subject: [PATCH 3/9] Remove `N*f0` symbols (#121) There's no Integer between 0 and 1/2, so these symbols are meaningless. --- src/normed.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/normed.jl b/src/normed.jl index 67b87e3a..f888f74d 100644 --- a/src/normed.jl +++ b/src/normed.jl @@ -16,7 +16,7 @@ typechar(::Type{X}) where {X <: Normed} = 'N' signbits(::Type{X}) where {X <: Normed} = 0 for T in (UInt8, UInt16, UInt32, UInt64) - for f in 0:sizeof(T)*8 + for f in 1:sizeof(T)*8 sym = Symbol(String(take!(showtype(_iotypealias, Normed{T,f})))) @eval begin const $sym = Normed{$T,$f} From 279ea8a4af8e3385531fc74a3c3c2f61ceee4eef Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Wed, 15 May 2019 22:20:27 +0800 Subject: [PATCH 4/9] enhance and export floattype (#122) --- src/FixedPointNumbers.jl | 30 ++++++++++++++++++++++++++++++ test/runtests.jl | 4 ++++ test/traits.jl | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 test/traits.jl diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 9e77efa2..b008f4be 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -23,6 +23,7 @@ export FixedPoint, Fixed, Normed, + floattype, # "special" typealiases # Q and U typealiases are exported in separate source files # Functions @@ -74,9 +75,38 @@ widen1(::Type{UInt128}) = UInt128 widen1(x::Integer) = x % widen1(typeof(x)) const ShortInts = Union{Int8,UInt8,Int16,UInt16} +const LongInts = Union{UInt64, UInt128, Int64, Int128, BigInt} +""" + floattype(::Type{T}) + +Return the minimum float type that represents `T` without overflow to `Inf`. + +# Example + +A classic usage is to avoid overflow behavior by promoting `FixedPoint` to `AbstractFloat` + +```julia +julia> x = N0f8(1.0) +1.0N0f8 + +julia> x + x # overflow +0.996N0f8 + +julia> float_x = floattype(eltype(x))(x) +1.0f0 + +julia> float_x + float_x +2.0f0 +``` +""" +floattype(::Type{T}) where {T <: Real} = T # fallback +floattype(::Type{T}) where {T <: Union{ShortInts, Bool}} = Float32 +floattype(::Type{T}) where {T <: Integer} = Float64 +floattype(::Type{T}) where {T <: LongInts} = BigFloat floattype(::Type{FixedPoint{T,f}}) where {T <: ShortInts,f} = Float32 floattype(::Type{FixedPoint{T,f}}) where {T <: Integer,f} = Float64 +floattype(::Type{FixedPoint{T,f}}) where {T <: LongInts,f} = BigFloat floattype(::Type{F}) where {F <: FixedPoint} = floattype(supertype(F)) floattype(x::FixedPoint) = floattype(typeof(x)) diff --git a/test/runtests.jl b/test/runtests.jl index 53f53ca6..570cec53 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,3 +8,7 @@ end @testset "fixed" begin include("fixed.jl") end + +@testset "traits" begin + include("traits.jl") +end diff --git a/test/traits.jl b/test/traits.jl new file mode 100644 index 00000000..874a47b4 --- /dev/null +++ b/test/traits.jl @@ -0,0 +1,19 @@ +@testset "floattype" begin + function _is_fixed_type(x::Symbol) + try + @eval $(x) isa Type && $(x) <: FixedPoint && return true + catch + return false + end + end + + fixed_types = setdiff(filter(_is_fixed_type, names(FixedPointNumbers)), [:Fixed, :Normed, :FixedPoint]) + fixed_types = [@eval $(x) for x in fixed_types] + + exact_types = vcat([UInt8, UInt16, UInt32, UInt64, UInt128, Bool, + Int8, Int16, Int32, Int64, Int128], + fixed_types) + for T in exact_types + @test typemax(T) <= maxintfloat(floattype(T)) + end +end From 0d72abf28bf89dfe52206de40553ef5001a0e61d Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Thu, 16 May 2019 11:23:01 +0800 Subject: [PATCH 5/9] make generate_fixedpoint_types a test utils This helps improve test type coverage --- test/traits.jl | 13 +------------ test/utils.jl | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 test/utils.jl diff --git a/test/traits.jl b/test/traits.jl index 874a47b4..9b817721 100644 --- a/test/traits.jl +++ b/test/traits.jl @@ -1,18 +1,7 @@ @testset "floattype" begin - function _is_fixed_type(x::Symbol) - try - @eval $(x) isa Type && $(x) <: FixedPoint && return true - catch - return false - end - end - - fixed_types = setdiff(filter(_is_fixed_type, names(FixedPointNumbers)), [:Fixed, :Normed, :FixedPoint]) - fixed_types = [@eval $(x) for x in fixed_types] - exact_types = vcat([UInt8, UInt16, UInt32, UInt64, UInt128, Bool, Int8, Int16, Int32, Int64, Int128], - fixed_types) + generate_fixedpoint_types()) for T in exact_types @test typemax(T) <= maxintfloat(floattype(T)) end diff --git a/test/utils.jl b/test/utils.jl new file mode 100644 index 00000000..7cc88404 --- /dev/null +++ b/test/utils.jl @@ -0,0 +1,18 @@ +""" return true if symbol `x` is a `ST` type""" +function _is_type(x::Symbol, ST::Symbol) + try + @eval $(x) isa Type && $(x) <: $(ST) && return true + catch + return false + end +end + +""" + generate_fixedpoint_types(ST::Symbol=:FixedPoint) + +generate a list of concrete `ST` types, where `ST ∈ (:FixedPoint, :Fixed, :Normed)` +""" +function generate_fixedpoint_types(ST::Symbol=:FixedPoint) + fixed_types = setdiff(filter(x->_is_type(x, ST), names(FixedPointNumbers)), [:Fixed, :Normed, :FixedPoint]) + fixed_types = [@eval $(x) for x in fixed_types] +end From 8b19b8d07ce368020ec019d03f9737a64fd68553 Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Thu, 16 May 2019 11:28:50 +0800 Subject: [PATCH 6/9] improve coverage of isinteger --- test/fixed.jl | 8 +++++--- test/normed.jl | 8 +++++--- test/runtests.jl | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/fixed.jl b/test/fixed.jl index 164047c3..b2eca4a9 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -148,9 +148,11 @@ end @testset "isinteger" begin # issue #120 - for T in (Fixed{Int8,6}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) - T_ints = round.(clamp.(rand(Int, 50, 50), typemin(T), typemax(T))) - @test all(isinteger.(T.(T_ints))) + for T in generate_fixedpoint_types(:Fixed) + T_ints = T.(clamp.(rand(rawtype(T), 500, 500), + ceil(BigInt, floattype(T)(typemin(T))), + floor(BigInt, floattype(T)(typemax(T))))) + @test all(isinteger.(T_ints)) end end diff --git a/test/normed.jl b/test/normed.jl index 7b18efde..fbefdc0c 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -347,9 +347,11 @@ end @testset "isinteger" begin # issue #120 - for T in (Normed{UInt8,6}, Normed{UInt16,8}, Normed{UInt16,10}, Normed{UInt32,16}) - a = round.(clamp.(rand(Int, 50, 50), typemin(T), typemax(T))) - @test all(isinteger.(T.(a))) + for T in generate_fixedpoint_types(:Normed) + T_ints = T.(clamp.(rand(rawtype(T), 500, 500), + ceil(BigInt, floattype(T)(typemin(T))), + floor(BigInt, floattype(T)(typemax(T))))) + @test all(isinteger.(T_ints)) end end diff --git a/test/runtests.jl b/test/runtests.jl index 570cec53..b15218d1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,5 @@ using FixedPointNumbers, Test +using FixedPointNumbers: rawtype @test isempty(detect_ambiguities(FixedPointNumbers, Base, Core)) From e9b2da114d9b92448f6f410b9ea0e15fad32e7d0 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 16 May 2019 11:42:30 +0800 Subject: [PATCH 7/9] include utils.jl --- test/runtests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index b15218d1..5c6c2bde 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,6 +3,8 @@ using FixedPointNumbers: rawtype @test isempty(detect_ambiguities(FixedPointNumbers, Base, Core)) +include("utils.jl") + @testset "normed" begin include("normed.jl") end From 561eb949689957b92945acbb23fc9710563740bd Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Thu, 16 May 2019 13:50:11 +0800 Subject: [PATCH 8/9] change BigInt to rawtype --- test/fixed.jl | 4 ++-- test/normed.jl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/fixed.jl b/test/fixed.jl index b2eca4a9..c474ba99 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -150,8 +150,8 @@ end # issue #120 for T in generate_fixedpoint_types(:Fixed) T_ints = T.(clamp.(rand(rawtype(T), 500, 500), - ceil(BigInt, floattype(T)(typemin(T))), - floor(BigInt, floattype(T)(typemax(T))))) + ceil(rawtype(T), floattype(T)(typemin(T))), + floor(rawtype(T), floattype(T)(typemax(T))))) @test all(isinteger.(T_ints)) end end diff --git a/test/normed.jl b/test/normed.jl index fbefdc0c..eff4ff04 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -349,8 +349,8 @@ end # issue #120 for T in generate_fixedpoint_types(:Normed) T_ints = T.(clamp.(rand(rawtype(T), 500, 500), - ceil(BigInt, floattype(T)(typemin(T))), - floor(BigInt, floattype(T)(typemax(T))))) + ceil(rawtype(T), floattype(T)(typemin(T))), + floor(rawtype(T), floattype(T)(typemax(T))))) @test all(isinteger.(T_ints)) end end From d9a12013fe3d1592904785f05e0eba6ac7bd6ba4 Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Thu, 16 May 2019 13:52:47 +0800 Subject: [PATCH 9/9] disable unrelated CI --- .travis.yml => .travis.yml.bak | 0 appveyor.yml | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename .travis.yml => .travis.yml.bak (100%) diff --git a/.travis.yml b/.travis.yml.bak similarity index 100% rename from .travis.yml rename to .travis.yml.bak diff --git a/appveyor.yml b/appveyor.yml index 96cfc7b6..42b2b465 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,12 +1,12 @@ environment: matrix: - julia_version: 1.0 - - julia_version: 1 - - julia_version: nightly + # - julia_version: 1 + # - julia_version: nightly platform: - x86 # 32-bit - - x64 # 64-bit + # - x64 # 64-bit ## uncomment the following lines to allow failures on nightly julia ## (tests will run but not make your overall status red)