From 408033af4be645d0c4654459a2d8edc388344ab4 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Fri, 8 Jun 2018 16:25:03 -0400 Subject: [PATCH 01/10] Fix all v0.7 deprecations and errors, and convert tests to testsets --- REQUIRE | 3 +- src/FixedPointNumbers.jl | 10 +- src/fixed.jl | 2 +- src/normed.jl | 4 +- test/fixed.jl | 189 +++++++------- test/normed.jl | 517 +++++++++++++++++++++------------------ test/runtests.jl | 11 +- 7 files changed, 394 insertions(+), 342 deletions(-) diff --git a/REQUIRE b/REQUIRE index dcd0aba7..4aa321c1 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1 @@ -julia 0.6 -Compat 0.35 +julia 0.7- diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index d30f12aa..9bb14d27 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -111,7 +111,7 @@ function show(io::IO, x::FixedPoint{T,f}) where {T,f} showtype(io, typeof(x)) end const _log2_10 = 3.321928094887362 -showcompact(io::IO, x::FixedPoint{T,f}) where {T,f} = show(io, round(convert(Float64,x), ceil(Int,f/_log2_10))) +showcompact(io::IO, x::FixedPoint{T,f}) where {T,f} = show(io, round(convert(Float64,x), digits=ceil(Int,f/_log2_10))) if VERSION >= v"0.7.0-DEV.1790" function Base.showarg(io::IO, a::Array{T}, toplevel) where {T<:FixedPoint} @@ -147,12 +147,12 @@ if isdefined(Base, :r_promote) Base.reducedim_initarray(A, region, oneunit(Treduce)) else # Julia v0.7 - Base.add_sum(x::FixedPoint, y::FixedPoint) = Treduce(x) + Treduce(y) + Base.add_sum(x::FixedPoint, y::FixedPoint) = convert(Treduce, x) + convert(Treduce, y) Base.reduce_empty(::typeof(Base.add_sum), ::Type{F}) where {F<:FixedPoint} = zero(Treduce) - Base.reduce_first(::typeof(Base.add_sum), x::FixedPoint) = Treduce(x) - Base.mul_prod(x::FixedPoint, y::FixedPoint) = Treduce(x) * Treduce(y) + Base.reduce_first(::typeof(Base.add_sum), x::FixedPoint) = convert(Treduce, x) + Base.mul_prod(x::FixedPoint, y::FixedPoint) = convert(Treduce, x) * convert(Treduce, y) Base.reduce_empty(::typeof(Base.mul_prod), ::Type{F}) where {F<:FixedPoint} = one(Treduce) - Base.reduce_first(::typeof(Base.mul_prod), x::FixedPoint) = Treduce(x) + Base.reduce_first(::typeof(Base.mul_prod), x::FixedPoint) = convert(Treduce, x) end diff --git a/src/fixed.jl b/src/fixed.jl index b0eb87ce..5c80cc96 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -7,7 +7,7 @@ struct Fixed{T <: Signed,f} <: FixedPoint{T, f} Fixed{T, f}(i::Integer, _) where {T,f} = new{T, f}(i % T) Fixed{T, f}(x) where {T,f} = convert(Fixed{T,f}, x) Fixed{T, f}(x::Fixed{T,f}) where {T,f} = x - Fixed{T, f}(x::Char) where {T,f} = throw(ArgumentError("Fixed cannot be constructed from a Char")) + Fixed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Fixed cannot be constructed from a Char")) Fixed{T, f}(x::Complex) where {T,f} = Fixed{T, f}(convert(real(typeof(x)), x)) Fixed{T, f}(x::Base.TwicePrecision) where {T,f} = Fixed{T, f}(convert(Float64, x)) end diff --git a/src/normed.jl b/src/normed.jl index 9ebdbd2c..c094c286 100644 --- a/src/normed.jl +++ b/src/normed.jl @@ -7,7 +7,7 @@ struct Normed{T<:Unsigned,f} <: FixedPoint{T,f} Normed{T, f}(i::Integer,_) where {T,f} = new{T, f}(i%T) # for setting by raw representation Normed{T, f}(x) where {T,f} = convert(Normed{T,f}, x) Normed{T, f}(x::Normed{T,f}) where {T,f} = x - Normed{T, f}(x::Char) where {T,f} = throw(ArgumentError("Normed cannot be constructed from a Char")) + Normed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Normed cannot be constructed from a Char")) Normed{T, f}(x::Complex) where {T,f} = Normed{T, f}(convert(real(typeof(x)), x)) Normed{T, f}(x::Base.TwicePrecision) where {T,f} = Normed{T, f}(convert(Float64, x)) end @@ -61,7 +61,7 @@ _convert(::Type{U}, ::Type{UInt128}, x::Float16) where {U <: Normed} = _convert(U, UInt128, Float32(x)) function _convert(::Type{U}, ::Type{UInt128}, x) where {U <: Normed} y = round(rawone(U)*x) # for UInt128, we can't widen - (0 <= y) & (y <= typemax(UInt128)) & (x <= Float64(typemax(U))) || throw_converterror(U, x) + (0 <= y) & (y <= typemax(UInt128)) & (x <= convert(Float64, typemax(U))) || throw_converterror(U, x) U(_unsafe_trunc(UInt128, y), 0) end diff --git a/test/fixed.jl b/test/fixed.jl index ab8d7fa4..55acc775 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -49,102 +49,121 @@ function test_fixed(::Type{T}, f) where {T} end end -@test isapprox(convert(Fixed{Int8,7}, 0.8), 0.797, atol=0.001) -@test isapprox(convert(Fixed{Int8,7}, 0.9), 0.898, atol=0.001) -@test_throws InexactError convert(Fixed{Int8, 7}, 0.999) -@test_throws InexactError convert(Fixed{Int8, 7}, 1.0) -@test_throws InexactError convert(Fixed{Int8, 7}, 1) -@test_throws InexactError convert(Fixed{Int8, 7}, 2) -@test_throws InexactError convert(Fixed{Int8, 7}, 128) - -for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] - T = Fixed{TI,f} - println(" Testing $T") - test_fixed(T, f) +@testset "conversion" begin + @test isapprox(convert(Fixed{Int8,7}, 0.8), 0.797, atol=0.001) + @test isapprox(convert(Fixed{Int8,7}, 0.9), 0.898, atol=0.001) + @test_throws InexactError convert(Fixed{Int8, 7}, 0.999) + @test_throws InexactError convert(Fixed{Int8, 7}, 1.0) + @test_throws InexactError convert(Fixed{Int8, 7}, 1) + @test_throws InexactError convert(Fixed{Int8, 7}, 2) + @test_throws InexactError convert(Fixed{Int8, 7}, 128) end -T = Fixed{Int8,7} -for i = -1.0:0.1:typemax(T) - @test i % T === T(i) +@testset "test_fixed" begin + for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] + T = Fixed{TI,f} + println(" Testing $T") + test_fixed(T, f) + end +end + +@testset "modulus" begin + T = Fixed{Int8,7} + for i = -1.0:0.1:typemax(T) + @test i % T === T(i) + end + @test ( 1.5 % T).i == round(Int, 1.5*128) % Int8 + @test (-0.3 % T).i == round(Int, -0.3*128) % Int8 + + T = Fixed{Int16,9} + for i = -64.0:0.1:typemax(T) + @test i % T === T(i) + end + @test ( 65.2 % T).i == round(Int, 65.2*512) % Int16 + @test (-67.2 % T).i == round(Int, -67.2*512) % Int16 +end + +@testset "testapprox" begin + for T in [Fixed{Int8,7}, Fixed{Int16,8}, Fixed{Int16,10}] + testapprox(T) # defined in ufixed.jl + end +end + +@testset "reductions" begin + F8 = Fixed{Int8,8} + a = F8[0.498, 0.1] + acmp = convert(Float64, a[1]) + convert(Float64, a[2]) + @test sum(a) == acmp + @test sum(a, dims=1) == [acmp] + + F6 = Fixed{Int8,6} + a = F6[1.2, 1.4] + acmp = convert(Float64, a[1])*convert(Float64, a[2]) + @test prod(a) == acmp + @test prod(a, dims=1) == [acmp] +end + +@testset "convert result type" begin + x = Fixed{Int8,8}(0.3) + for T in (Float16, Float32, Float64, BigFloat) + y = convert(T, x) + @test isa(y, T) + end +end + +@testset "Integer conversions" begin + @test convert(Int, Q1f6(1)) === 1 + @test convert(Integer, Q1f6(1)) === Int8(1) end -@test ( 1.5 % T).i == round(Int, 1.5*128) % Int8 -@test (-0.3 % T).i == round(Int, -0.3*128) % Int8 -T = Fixed{Int16,9} -for i = -64.0:0.1:typemax(T) - @test i % T === T(i) +@testset "Floating-point conversions" begin + @test isa(float(one(Fixed{Int8,6})), Float32) + @test isa(float(one(Fixed{Int32,18})), Float64) + @test isa(float(one(Fixed{Int32,25})), Float64) end -@test ( 65.2 % T).i == round(Int, 65.2*512) % Int16 -@test (-67.2 % T).i == round(Int, -67.2*512) % Int16 -for T in [Fixed{Int8,7}, Fixed{Int16,8}, Fixed{Int16,10}] - local T - testapprox(T) # defined in ufixed.jl +@testset "Show" begin + x = Fixed{Int32,5}(0.25) + iob = IOBuffer() + show(iob, x) + str = String(take!(iob)) + @test str == "0.25Q26f5" + @test eval(Meta.parse(str)) == x end -# reductions -F8 = Fixed{Int8,8} -a = F8[0.498, 0.1] -acmp = Float64(a[1]) + Float64(a[2]) -@test sum(a) == acmp -@test sum(a, 1) == [acmp] - -F6 = Fixed{Int8,6} -a = F6[1.2, 1.4] -acmp = Float64(a[1])*Float64(a[2]) -@test prod(a) == acmp -@test prod(a, 1) == [acmp] - -x = Fixed{Int8,8}(0.3) -for T in (Float16, Float32, Float64, BigFloat) - local T - y = convert(T, x) - @test isa(y, T) +@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 + @test size(a) == (3,5) + end end -@test convert(Int, Q1f6(1)) === 1 -@test convert(Integer, Q1f6(1)) === Int8(1) - -# Floating-point conversions -@test isa(float(one(Fixed{Int8,6})), Float32) -@test isa(float(one(Fixed{Int32,18})), Float64) -@test isa(float(one(Fixed{Int32,25})), Float64) - -# Show -x = Fixed{Int32,5}(0.25) -iob = IOBuffer() -show(iob, x) -str = String(take!(iob)) -@test str == "0.25Q26f5" -@test eval(parse(str)) == x - -for T in (Fixed{Int8,8}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) - local T - a = rand(T) - @test isa(a, T) - a = rand(T, (3, 5)) - @test ndims(a) == 2 && eltype(a) == T - @test size(a) == (3,5) +@testset "realmin" begin + # issue #79 + @test realmin(Q11f4) == Q11f4(0.06) end -# issue #79 -@test realmin(Q11f4) == Q11f4(0.06) - -# Test disambiguation constructors -@test_throws ArgumentError Fixed{Int32,16}('a') -@test_throws InexactError Fixed{Int32,16}(complex(1.0, 1.0)) -@test Fixed{Int32,16}(complex(1.0, 0.0)) == 1 -@test Fixed{Int32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 - -# test all-fractional fixed-point numbers (issue #104) -for (T, f) in ((Int8, 7), - (Int16, 15), - (Int32, 31), - (Int64, 63)) - tmax = typemax(Fixed{T, f}) - @test tmax == BigInt(typemax(T)) / BigInt(2)^f - tol = (tmax + BigFloat(1.0)) / (sizeof(T) * 8) - for x in linspace(-1, BigFloat(tmax)-tol, 50) - @test abs(Fixed{T, f}(x) - x) <= tol +@testset "Disambiguation constructors" begin + @test_throws ArgumentError Fixed{Int32,16}('a') + @test_throws InexactError Fixed{Int32,16}(complex(1.0, 1.0)) + @test Fixed{Int32,16}(complex(1.0, 0.0)) == 1 + @test Fixed{Int32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 +end + +@testset "fractional fixed-point numbers" begin + # test all-fractional fixed-point numbers (issue #104) + for (T, f) in ((Int8, 7), + (Int16, 15), + (Int32, 31), + (Int64, 63)) + tmax = typemax(Fixed{T, f}) + @test tmax == BigInt(typemax(T)) / BigInt(2)^f + tol = (tmax + BigFloat(1.0)) / (sizeof(T) * 8) + for x in range(-1, stop=convert(BigFloat, tmax)-tol, length=50) + @test abs(Fixed{T, f}(x) - x) <= tol + end end end diff --git a/test/normed.jl b/test/normed.jl index 70a88416..1dc0e64a 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -1,145 +1,162 @@ using FixedPointNumbers, Compat.Test -@test reinterpret(N0f8, 0xa2).i === 0xa2 -@test reinterpret(N6f10, 0x1fa2).i === 0x1fa2 -@test reinterpret(N4f12, 0x1fa2).i === 0x1fa2 -@test reinterpret(N2f14, 0x1fa2).i === 0x1fa2 -@test reinterpret(N0f16, 0x1fa2).i === 0x1fa2 - -@test reinterpret(reinterpret(N0f8, 0xa2)) === 0xa2 -@test reinterpret(reinterpret(N6f10, 0x00a2)) === 0x00a2 -@test reinterpret(reinterpret(N4f12, 0x00a2)) === 0x00a2 -@test reinterpret(reinterpret(N2f14, 0x00a2)) === 0x00a2 -@test reinterpret(reinterpret(N0f16, 0x00a2)) === 0x00a2 - -@test 0.635N0f8 == N0f8(0.635) -@test 0.635N6f10 == N6f10(0.635) -@test 0.635N4f12 == N4f12(0.635) -@test 0.635N2f14 == N2f14(0.635) -@test 0.635N0f16 == N0f16(0.635) - -@test N0f8(1.0) == reinterpret(N0f8, 0xff) -@test N0f8(0.5) == reinterpret(N0f8, 0x80) -@test N2f14(1.0) == reinterpret(N2f14, 0x3fff) -v = N4f12.([2]) -@test v == N4f12[reinterpret(N4f12, 0x1ffe)] -@test isa(v, Vector{N4f12}) +@testset "reinterpret" begin + @test reinterpret(N0f8, 0xa2).i === 0xa2 + @test reinterpret(N6f10, 0x1fa2).i === 0x1fa2 + @test reinterpret(N4f12, 0x1fa2).i === 0x1fa2 + @test reinterpret(N2f14, 0x1fa2).i === 0x1fa2 + @test reinterpret(N0f16, 0x1fa2).i === 0x1fa2 + + @test reinterpret(reinterpret(N0f8, 0xa2)) === 0xa2 + @test reinterpret(reinterpret(N6f10, 0x00a2)) === 0x00a2 + @test reinterpret(reinterpret(N4f12, 0x00a2)) === 0x00a2 + @test reinterpret(reinterpret(N2f14, 0x00a2)) === 0x00a2 + @test reinterpret(reinterpret(N0f16, 0x00a2)) === 0x00a2 + + @test 0.635N0f8 == N0f8(0.635) + @test 0.635N6f10 == N6f10(0.635) + @test 0.635N4f12 == N4f12(0.635) + @test 0.635N2f14 == N2f14(0.635) + @test 0.635N0f16 == N0f16(0.635) + + @test N0f8(1.0) == reinterpret(N0f8, 0xff) + @test N0f8(0.5) == reinterpret(N0f8, 0x80) + @test N2f14(1.0) == reinterpret(N2f14, 0x3fff) + v = N4f12.([2]) + @test v == N4f12[reinterpret(N4f12, 0x1ffe)] + @test isa(v, Vector{N4f12}) +end UF2 = (Normed{UInt32,16}, Normed{UInt64,3}, Normed{UInt64,51}, Normed{UInt128,7}, Normed{UInt128,51}) -for T in (FixedPointNumbers.UF..., UF2...) - @test zero(T) == 0 - @test one(T) == 1 - @test one(T) * one(T) == one(T) - @test typemin(T) == 0 - @test realmin(T) == eps(T) - @test eps(zero(T)) == eps(typemax(T)) - @test sizeof(T) == sizeof(FixedPointNumbers.rawtype(T)) +@testset "limits and identities" begin + + for T in (FixedPointNumbers.UF..., UF2...) + @test zero(T) == 0 + @test one(T) == 1 + @test one(T) * one(T) == one(T) + @test typemin(T) == 0 + @test realmin(T) == eps(T) + @test eps(zero(T)) == eps(typemax(T)) + @test sizeof(T) == sizeof(FixedPointNumbers.rawtype(T)) + end + @test typemax(N0f8) == 1 + @test typemax(N6f10) == typemax(UInt16)//(2^10-1) + @test typemax(N4f12) == typemax(UInt16)//(2^12-1) + @test typemax(N2f14) == typemax(UInt16)//(2^14-1) + @test typemax(N0f16) == 1 + @test typemax(N6f10) == typemax(UInt16) // (2^10-1) + @test typemax(N4f12) == typemax(UInt16) // (2^12-1) + @test typemax(N2f14) == typemax(UInt16) // (2^14-1) + @test typemax(Normed{UInt32,16}) == typemax(UInt32) // (2^16-1) + @test typemax(Normed{UInt64,3}) == typemax(UInt64) // (2^3-1) + @test typemax(Normed{UInt128,7}) == typemax(UInt128) // (2^7-1) + @test typemax(Normed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-1) end -@test typemax(N0f8) == 1 -@test typemax(N6f10) == typemax(UInt16)//(2^10-1) -@test typemax(N4f12) == typemax(UInt16)//(2^12-1) -@test typemax(N2f14) == typemax(UInt16)//(2^14-1) -@test typemax(N0f16) == 1 -@test typemax(N6f10) == typemax(UInt16) // (2^10-1) -@test typemax(N4f12) == typemax(UInt16) // (2^12-1) -@test typemax(N2f14) == typemax(UInt16) // (2^14-1) -@test typemax(Normed{UInt32,16}) == typemax(UInt32) // (2^16-1) -@test typemax(Normed{UInt64,3}) == typemax(UInt64) // (2^3-1) -@test typemax(Normed{UInt128,7}) == typemax(UInt128) // (2^7-1) -@test typemax(Normed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-1) - -# TODO: change back to InexactError when it allows message strings -@test_throws ArgumentError N0f8(2) -@test_throws ArgumentError N0f8(255) -@test_throws ArgumentError N0f8(0xff) -@test_throws ArgumentError N0f16(2) -@test_throws ArgumentError N0f16(0xff) -@test_throws ArgumentError N0f16(0xffff) -@test_throws ArgumentError convert(N0f8, typemax(N6f10)) -@test_throws ArgumentError convert(N0f16, typemax(N6f10)) -@test_throws ArgumentError convert(Normed{UInt128,100}, 10^9) -@test_throws ArgumentError convert(Normed{UInt128,100}, 10.0^9) - -x = N0f8(0.5) -@test convert(N0f8, x) === x -@test isfinite(x) == true -@test isnan(x) == false -@test isinf(x) == false - -@test convert(N0f8, 1.1/typemax(UInt8)) == eps(N0f8) -@test convert(N6f10, 1.1/typemax(UInt16)*64) == eps(N6f10) -@test convert(N4f12, 1.1/typemax(UInt16)*16) == eps(N4f12) -@test convert(N2f14, 1.1/typemax(UInt16)*4) == eps(N2f14) -@test convert(N0f16, 1.1/typemax(UInt16)) == eps(N0f16) -@test convert(Normed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(Normed{UInt32,16}) -@test convert(Normed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(Normed{UInt64,3}) -@test convert(Normed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(Normed{UInt128,7}) - -@test convert(N0f8, 1.1f0/typemax(UInt8)) == eps(N0f8) - -@test convert(Float64, eps(N0f8)) == 1/typemax(UInt8) -@test convert(Float32, eps(N0f8)) == 1.0f0/typemax(UInt8) -@test convert(BigFloat, eps(N0f8)) == BigFloat(1)/typemax(UInt8) -for T in (FixedPointNumbers.UF..., UF2...) - @test convert(Bool, zero(T)) == false - @test convert(Bool, one(T)) == true - @test convert(Bool, convert(T, 0.2)) == true - @test convert(Int, one(T)) == 1 - @test convert(Integer, one(T)) == 1 - @test convert(Rational, one(T)) == 1 + +@testset "inexactness" begin + # TODO: change back to InexactError when it allows message strings + @test_throws ArgumentError N0f8(2) + @test_throws ArgumentError N0f8(255) + @test_throws ArgumentError N0f8(0xff) + @test_throws ArgumentError N0f16(2) + @test_throws ArgumentError N0f16(0xff) + @test_throws ArgumentError N0f16(0xffff) + @test_throws ArgumentError convert(N0f8, typemax(N6f10)) + @test_throws ArgumentError convert(N0f16, typemax(N6f10)) + @test_throws ArgumentError convert(Normed{UInt128,100}, 10^9) + @test_throws ArgumentError convert(Normed{UInt128,100}, 10.0^9) end -@test convert(Rational, convert(N0f8, 0.5)) == 0x80//0xff -@test convert(N0f16, one(N0f8)) === one(N0f16) -@test convert(N0f16, N0f8(0.5)).i === 0x8080 -@test convert(Normed{UInt16,7}, Normed{UInt8,7}(0.504)) === Normed{UInt16,7}(0.504) -@test N0f8(0.2) % N0f8 === N0f8(0.2) -@test N2f14(1.2) % N0f16 === N0f16(0.20002) -@test N2f14(1.2) % N0f8 === N0f8(0.196) +@testset "conversion" begin + x = N0f8(0.5) + @test convert(N0f8, x) === x + @test isfinite(x) == true + @test isnan(x) == false + @test isinf(x) == false + + @test convert(N0f8, 1.1/typemax(UInt8)) == eps(N0f8) + @test convert(N6f10, 1.1/typemax(UInt16)*64) == eps(N6f10) + @test convert(N4f12, 1.1/typemax(UInt16)*16) == eps(N4f12) + @test convert(N2f14, 1.1/typemax(UInt16)*4) == eps(N2f14) + @test convert(N0f16, 1.1/typemax(UInt16)) == eps(N0f16) + @test convert(Normed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(Normed{UInt32,16}) + @test convert(Normed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(Normed{UInt64,3}) + @test convert(Normed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(Normed{UInt128,7}) + + @test convert(N0f8, 1.1f0/typemax(UInt8)) == eps(N0f8) + + @test convert(Float64, eps(N0f8)) == 1/typemax(UInt8) + @test convert(Float32, eps(N0f8)) == 1.0f0/typemax(UInt8) + @test convert(BigFloat, eps(N0f8)) == BigFloat(1)/typemax(UInt8) + for T in (FixedPointNumbers.UF..., UF2...) + @test convert(Bool, zero(T)) == false + @test convert(Bool, one(T)) == true + @test convert(Bool, convert(T, 0.2)) == true + @test convert(Int, one(T)) == 1 + @test convert(Integer, one(T)) == 1 + @test convert(Rational, one(T)) == 1 + end + @test convert(Rational, convert(N0f8, 0.5)) == 0x80//0xff + @test convert(N0f16, one(N0f8)) === one(N0f16) + @test convert(N0f16, N0f8(0.5)).i === 0x8080 + @test convert(Normed{UInt16,7}, Normed{UInt8,7}(0.504)) === Normed{UInt16,7}(0.504) +end + +@testset "modulus" begin + @test N0f8(0.2) % N0f8 === N0f8(0.2) + @test N2f14(1.2) % N0f16 === N0f16(0.20002) + @test N2f14(1.2) % N0f8 === N0f8(0.196) + + for i = 0.0:0.1:1.0 + @test i % N0f8 === N0f8(i) + end + @test ( 1.5 % N0f8).i == round(Int, 1.5*255) % UInt8 + @test (-0.3 % N0f8).i == round(Int, -0.3*255) % UInt8 + + for i = 0.0:0.1:64.0 + @test i % N6f10 === N6f10(i) + end + @test (65.2 % N6f10).i == round(Int, 65.2*1023) % UInt16 + @test (-0.3 % N6f10).i == round(Int, -0.3*1023) % UInt16 -for i = 0.0:0.1:1.0 - @test i % N0f8 === N0f8(i) + @test 1 % N0f8 == 1 + @test 2 % N0f8 == N0f8(0.996) end -@test ( 1.5 % N0f8).i == round(Int, 1.5*255) % UInt8 -@test (-0.3 % N0f8).i == round(Int, -0.3*255) % UInt8 -for i = 0.0:0.1:64.0 - @test i % N6f10 === N6f10(i) +@testset "bitwise" begin + x = N0f8(0b01010001, 0) + @test ~x == N0f8(0b10101110, 0) + @test -x == reinterpret(N0f8, 0xaf) end -@test (65.2 % N6f10).i == round(Int, 65.2*1023) % UInt16 -@test (-0.3 % N6f10).i == round(Int, -0.3*1023) % UInt16 - -@test 1 % N0f8 == 1 -@test 2 % N0f8 == N0f8(0.996) - -x = N0f8(0b01010001, 0) -@test ~x == N0f8(0b10101110, 0) -@test -x == reinterpret(N0f8, 0xaf) - -@test isa(float(one(Normed{UInt8,7})), Float32) -@test isa(float(one(Normed{UInt32,18})), Float64) -@test isa(float(one(Normed{UInt32,25})), Float64) - -for T in (FixedPointNumbers.UF..., UF2...) - x = T(0x10,0) - y = T(0x25,0) - fx = float(x) - fy = float(y) - @test y > x - @test y != x - @test typeof(x+y) == T - @test typeof((x+y)-y) == T - @test typeof(x*y) == T - @test typeof(x/y) == T - @test (x+y) ≈ T(0x35,0) - @test ((x+y)-x) ≈ fy - @test ((x-y)+y) ≈ fx - @test (x*y) ≈ convert(T, fx*fy) - @test (x/y) ≈ convert(T, fx/fy) - @test (x^2) ≈ convert(T, fx^2) - @test (x^2.1f0) ≈ fx^2.1f0 - @test (x^2.1) ≈ convert(Float64, x)^2.1 + +@testset "float" begin + @test isa(float(one(Normed{UInt8,7})), Float32) + @test isa(float(one(Normed{UInt32,18})), Float64) + @test isa(float(one(Normed{UInt32,25})), Float64) +end + +@testset "arithmetic" begin + for T in (FixedPointNumbers.UF..., UF2...) + x = T(0x10,0) + y = T(0x25,0) + fx = float(x) + fy = float(y) + @test y > x + @test y != x + @test typeof(x+y) == T + @test typeof((x+y)-y) == T + @test typeof(x*y) == T + @test typeof(x/y) == T + @test (x+y) ≈ T(0x35,0) + @test ((x+y)-x) ≈ fy + @test ((x-y)+y) ≈ fx + @test (x*y) ≈ convert(T, fx*fy) + @test (x/y) ≈ convert(T, fx/fy) + @test (x^2) ≈ convert(T, fx^2) + @test (x^2.1f0) ≈ fx^2.1f0 + @test (x^2.1) ≈ convert(Float64, x)^2.1 + end end function testtrunc(inc::T) where {T} @@ -174,8 +191,10 @@ function testtrunc(inc::T) where {T} end end -for T in (FixedPointNumbers.UF..., UF2...) - testtrunc(eps(T)) +@testset "trunc" begin + for T in (FixedPointNumbers.UF..., UF2...) + testtrunc(eps(T)) + end end function testapprox(::Type{T}) where {T} @@ -186,66 +205,74 @@ function testapprox(::Type{T}) where {T} @test !(x ≈ y+eps(T)) end end -for T in FixedPointNumbers.UF - testapprox(T) + +@testset "approx" begin + for T in FixedPointNumbers.UF + testapprox(T) + end +end + +@testset "low-level arithmetic" begin + @test !(N0f8(0.5) < N0f8(0.5)) + @test N0f8(0.5) <= N0f8(0.5) + + @test div(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 + @test div(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 7 + @test Base.fld1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 + @test Base.fld1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 8 + @test mod(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 0 + @test mod(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) + @test mod1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x02) + @test mod1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) + @test bswap(N0f8(0.5)) === N0f8(0.5) + @test bswap(N0f16(0.5)) === reinterpret(N0f16, 0x0080) + @test minmax(N0f8(0.8), N0f8(0.2)) === (N0f8(0.2), N0f8(0.8)) + + r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48)) + @test length(r) == 48 +end + +@testset "step range" begin + counter = 0 + for x in N0f8(0):eps(N0f8):N0f8(1) + counter += 1 + end + @test counter == 256 end -@test !(N0f8(0.5) < N0f8(0.5)) -@test N0f8(0.5) <= N0f8(0.5) - -@test div(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 -@test div(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 7 -@test Base.fld1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 -@test Base.fld1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 8 -@test mod(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 0 -@test mod(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) -@test mod1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x02) -@test mod1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) -@test bswap(N0f8(0.5)) === N0f8(0.5) -@test bswap(N0f16(0.5)) === reinterpret(N0f16, 0x0080) -@test minmax(N0f8(0.8), N0f8(0.2)) === (N0f8(0.2), N0f8(0.8)) - -r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48)) -@test length(r) == 48 - -counter = 0 -for x in N0f8(0):eps(N0f8):N0f8(1) - local x - counter += 1 +@testset "Promotion within Normed" begin + @test @inferred(promote(N0f8(0.2), N0f8(0.8))) === + (N0f8(0.2), N0f8(0.8)) + @test @inferred(promote(Normed{UInt16,3}(0.2), Normed{UInt8,3}(0.86))) === + (Normed{UInt16,3}(0.2), Normed{UInt16,3}(0.86)) + @test @inferred(promote(Normed{UInt8,7}(0.197), Normed{UInt8,4}(0.8))) === + (Normed{UInt16,7}(0.197), Normed{UInt16,7}(0.8)) + + @test Normed{UInt16,16}(1) == Normed{UInt8,8}(1) + @test Normed{UInt16,16}(0.2) == Normed{UInt8,8}(0.2) + @test Normed{UInt16,8}(1) == Normed{UInt8,8}(1) + @test Normed{UInt16,8}(0.2) == Normed{UInt8,8}(0.2) + @test Normed{UInt16,16}(1) == Normed{UInt8,6}(1) + @test Normed{UInt16,16}(0.20635) == Normed{UInt8,6}(0.20635) + @test Normed{UInt16,4}(1) == Normed{UInt8,6}(1) + @test Normed{UInt16,4}(0.2) == Normed{UInt8,6}(0.2) + + @test promote_type(N0f8,Float32,Int) == Float32 + @test promote_type(N0f8,Int,Float32) == Float32 + @test promote_type(Int,N0f8,Float32) == Float32 + @test promote_type(Int,Float32,N0f8) == Float32 + @test promote_type(Float32,Int,N0f8) == Float32 + @test promote_type(Float32,N0f8,Int) == Float32 +end + +@testset "show" begin + x = reinterpret(N0f8, 0xaa) + iob = IOBuffer() + show(iob, x) + str = String(take!(iob)) + @test str == "0.667N0f8" + @test eval(Meta.parse(str)) == x end -@test counter == 256 - -# Promotion within Normed -@test @inferred(promote(N0f8(0.2), N0f8(0.8))) === - (N0f8(0.2), N0f8(0.8)) -@test @inferred(promote(Normed{UInt16,3}(0.2), Normed{UInt8,3}(0.86))) === - (Normed{UInt16,3}(0.2), Normed{UInt16,3}(0.86)) -@test @inferred(promote(Normed{UInt8,7}(0.197), Normed{UInt8,4}(0.8))) === - (Normed{UInt16,7}(0.197), Normed{UInt16,7}(0.8)) - -@test Normed{UInt16,16}(1) == Normed{UInt8,8}(1) -@test Normed{UInt16,16}(0.2) == Normed{UInt8,8}(0.2) -@test Normed{UInt16,8}(1) == Normed{UInt8,8}(1) -@test Normed{UInt16,8}(0.2) == Normed{UInt8,8}(0.2) -@test Normed{UInt16,16}(1) == Normed{UInt8,6}(1) -@test Normed{UInt16,16}(0.20635) == Normed{UInt8,6}(0.20635) -@test Normed{UInt16,4}(1) == Normed{UInt8,6}(1) -@test Normed{UInt16,4}(0.2) == Normed{UInt8,6}(0.2) - -@test promote_type(N0f8,Float32,Int) == Float32 -@test promote_type(N0f8,Int,Float32) == Float32 -@test promote_type(Int,N0f8,Float32) == Float32 -@test promote_type(Int,Float32,N0f8) == Float32 -@test promote_type(Float32,Int,N0f8) == Float32 -@test promote_type(Float32,N0f8,Int) == Float32 - -# Show -x = reinterpret(N0f8, 0xaa) -iob = IOBuffer() -show(iob, x) -str = String(take!(iob)) -@test str == "0.667N0f8" -@test eval(parse(str)) == x # scaledual function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number) @@ -256,67 +283,71 @@ function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number) C end -a = rand(UInt8, 10) -rfloat = similar(a, Float32) -rfixed = similar(rfloat) -af8 = reinterpret(N0f8, a) - -b = 0.5 -bd, eld = scaledual(b, af8[1]) -@assert b*a[1] == bd*eld - -b, ad = scaledual(0.5, a) -@test b == 0.5 -@test ad == a -b, ad = scaledual(0.5, ad) -generic_scale!(rfloat, a, 0.5) -generic_scale!(rfixed, ad, b) -@test rfloat == rfixed - -# reductions -a = N0f8[reinterpret(N0f8, 0xff), reinterpret(N0f8, 0xff)] -@test sum(a) == 2.0 -@test sum(a, 1) == [2.0] - -a = N2f14[3.2, 2.4] -acmp = Float64(a[1])*Float64(a[2]) -@test prod(a) == acmp -@test prod(a, 1) == [acmp] - -x = N0f8(0.3) -for T in (Float16, Float32, Float64, BigFloat) - y = convert(T, x) - @test isa(y, T) +@testset "scaledual" begin + a = rand(UInt8, 10) + rfloat = similar(a, Float32) + rfixed = similar(rfloat) + af8 = reinterpret(N0f8, a) + + b = 0.5 + bd, eld = scaledual(b, af8[1]) + @assert b*a[1] == bd*eld + + b, ad = scaledual(0.5, a) + @test b == 0.5 + @test ad == a + b, ad = scaledual(0.5, ad) + generic_scale!(rfloat, a, 0.5) + generic_scale!(rfixed, ad, b) + @test rfloat == rfixed +end + +@testset "reductions" begin + a = N0f8[reinterpret(N0f8, 0xff), reinterpret(N0f8, 0xff)] + @test sum(a) == 2.0 + @test sum(a, dims=1) == [2.0] + + a = N2f14[3.2, 2.4] + acmp = convert(Float64, a[1])*convert(Float64, a[2]) + @test prod(a) == acmp + @test prod(a, dims=1) == [acmp] end -for T in (Normed{UInt8,8}, Normed{UInt8,6}, - Normed{UInt16,16}, Normed{UInt16,14}, - Normed{UInt32,32}, Normed{UInt32,30}, - Normed{UInt64,64}, Normed{UInt64,62}) - a = rand(T) - @test isa(a, T) - a = rand(T, (3, 5)) - @test ndims(a) == 2 && eltype(a) == T - @test size(a) == (3,5) +@testset "convert" begin + x = N0f8(0.3) + for T in (Float16, Float32, Float64, BigFloat) + y = convert(T, x) + @test isa(y, T) + end end -# Overflow with Float16 -@test N0f16(Float16(1.0)) === N0f16(1.0) -@test Float16(1.0) % N0f16 === N0f16(1.0) +@testset "rand" begin + for T in (Normed{UInt8,8}, Normed{UInt8,6}, + Normed{UInt16,16}, Normed{UInt16,14}, + Normed{UInt32,32}, Normed{UInt32,30}, + Normed{UInt64,64}, Normed{UInt64,62}) + a = rand(T) + @test isa(a, T) + a = rand(T, (3, 5)) + @test ndims(a) == 2 && eltype(a) == T + @test size(a) == (3,5) + end +end -if VERSION >= v"0.7.0-DEV.2657" +@testset "Overflow with Float16" begin + @test N0f16(Float16(1.0)) === N0f16(1.0) + @test Float16(1.0) % N0f16 === N0f16(1.0) +end + +@testset "summary" begin a = N0f8[0.2, 0.4] @test summary(a) == "2-element Array{N0f8,1} with eltype Normed{UInt8,8}" @test summary(view(a, 1:2)) == "2-element view(::Array{N0f8,1}, 1:2) with eltype Normed{UInt8,8}" -elseif VERSION >= v"0.7.0-DEV.1790" - a = N0f8[0.2, 0.4] - @test summary(a) == "2-element Array{N0f8,1} with eltype FixedPointNumbers.Normed{UInt8,8}" - @test summary(view(a, 1:2)) == "2-element view(::Array{N0f8,1}, 1:2) with eltype FixedPointNumbers.Normed{UInt8,8}" end -# Test disambiguation constructors -@test_throws ArgumentError Normed{UInt32,16}('a') -@test_throws InexactError Normed{UInt32,16}(complex(1.0, 1.0)) -@test Normed{UInt32,16}(complex(1.0, 0.0)) == 1 -@test Normed{UInt32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 - +@testset "disambiguation constructors" begin + @test_throws ArgumentError Normed{UInt32,16}('a') + @test_throws InexactError Normed{UInt32,16}(complex(1.0, 1.0)) + @test Normed{UInt32,16}(complex(1.0, 0.0)) == 1 + @test Normed{UInt32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 +end diff --git a/test/runtests.jl b/test/runtests.jl index 488afa31..07b52040 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,8 +1,11 @@ -using FixedPointNumbers, Compat.Test +using FixedPointNumbers, Test @test isempty(detect_ambiguities(FixedPointNumbers, Base, Core)) -for f in ["normed.jl", "fixed.jl"] - println("Testing $f") - include(f) +@testset "normed" begin + include("normed.jl") +end + +@testset "fixed" begin + include("fixed.jl") end From 9f1b1af8ce23953c077c082a471015da863776e0 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Fri, 8 Jun 2018 16:43:34 -0400 Subject: [PATCH 02/10] update travis and appveyor versions --- .travis.yml | 2 +- appveyor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 73b3e297..2ae6fb61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ os: - linux - osx julia: - - 0.6 + - 0.7 - nightly notifications: email: false diff --git a/appveyor.yml b/appveyor.yml index 6d4b8b2a..d9d06300 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ environment: matrix: - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" From 8f46026cdd9463d410799d6361b0e992b5744ecc Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Fri, 8 Jun 2018 16:43:43 -0400 Subject: [PATCH 03/10] remove indentation changes --- test/fixed.jl | 156 ++++++++--------- test/normed.jl | 467 ++++++++++++++++++++++++------------------------- 2 files changed, 311 insertions(+), 312 deletions(-) diff --git a/test/fixed.jl b/test/fixed.jl index 55acc775..8c0012b2 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -50,120 +50,120 @@ function test_fixed(::Type{T}, f) where {T} end @testset "conversion" begin - @test isapprox(convert(Fixed{Int8,7}, 0.8), 0.797, atol=0.001) - @test isapprox(convert(Fixed{Int8,7}, 0.9), 0.898, atol=0.001) - @test_throws InexactError convert(Fixed{Int8, 7}, 0.999) - @test_throws InexactError convert(Fixed{Int8, 7}, 1.0) - @test_throws InexactError convert(Fixed{Int8, 7}, 1) - @test_throws InexactError convert(Fixed{Int8, 7}, 2) - @test_throws InexactError convert(Fixed{Int8, 7}, 128) +@test isapprox(convert(Fixed{Int8,7}, 0.8), 0.797, atol=0.001) +@test isapprox(convert(Fixed{Int8,7}, 0.9), 0.898, atol=0.001) +@test_throws InexactError convert(Fixed{Int8, 7}, 0.999) +@test_throws InexactError convert(Fixed{Int8, 7}, 1.0) +@test_throws InexactError convert(Fixed{Int8, 7}, 1) +@test_throws InexactError convert(Fixed{Int8, 7}, 2) +@test_throws InexactError convert(Fixed{Int8, 7}, 128) end @testset "test_fixed" begin - for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] - T = Fixed{TI,f} - println(" Testing $T") - test_fixed(T, f) - end +for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] + T = Fixed{TI,f} + println(" Testing $T") + test_fixed(T, f) +end end @testset "modulus" begin - T = Fixed{Int8,7} - for i = -1.0:0.1:typemax(T) - @test i % T === T(i) - end - @test ( 1.5 % T).i == round(Int, 1.5*128) % Int8 - @test (-0.3 % T).i == round(Int, -0.3*128) % Int8 +T = Fixed{Int8,7} +for i = -1.0:0.1:typemax(T) + @test i % T === T(i) +end +@test ( 1.5 % T).i == round(Int, 1.5*128) % Int8 +@test (-0.3 % T).i == round(Int, -0.3*128) % Int8 - T = Fixed{Int16,9} - for i = -64.0:0.1:typemax(T) - @test i % T === T(i) - end - @test ( 65.2 % T).i == round(Int, 65.2*512) % Int16 - @test (-67.2 % T).i == round(Int, -67.2*512) % Int16 +T = Fixed{Int16,9} +for i = -64.0:0.1:typemax(T) + @test i % T === T(i) +end +@test ( 65.2 % T).i == round(Int, 65.2*512) % Int16 +@test (-67.2 % T).i == round(Int, -67.2*512) % Int16 end @testset "testapprox" begin - for T in [Fixed{Int8,7}, Fixed{Int16,8}, Fixed{Int16,10}] - testapprox(T) # defined in ufixed.jl - end +for T in [Fixed{Int8,7}, Fixed{Int16,8}, Fixed{Int16,10}] + testapprox(T) # defined in ufixed.jl +end end @testset "reductions" begin - F8 = Fixed{Int8,8} - a = F8[0.498, 0.1] - acmp = convert(Float64, a[1]) + convert(Float64, a[2]) - @test sum(a) == acmp - @test sum(a, dims=1) == [acmp] - - F6 = Fixed{Int8,6} - a = F6[1.2, 1.4] - acmp = convert(Float64, a[1])*convert(Float64, a[2]) - @test prod(a) == acmp - @test prod(a, dims=1) == [acmp] +F8 = Fixed{Int8,8} +a = F8[0.498, 0.1] +acmp = convert(Float64, a[1]) + convert(Float64, a[2]) +@test sum(a) == acmp +@test sum(a, dims=1) == [acmp] + +F6 = Fixed{Int8,6} +a = F6[1.2, 1.4] +acmp = convert(Float64, a[1])*convert(Float64, a[2]) +@test prod(a) == acmp +@test prod(a, dims=1) == [acmp] end @testset "convert result type" begin - x = Fixed{Int8,8}(0.3) - for T in (Float16, Float32, Float64, BigFloat) - y = convert(T, x) - @test isa(y, T) - end +x = Fixed{Int8,8}(0.3) +for T in (Float16, Float32, Float64, BigFloat) + y = convert(T, x) + @test isa(y, T) +end end @testset "Integer conversions" begin - @test convert(Int, Q1f6(1)) === 1 - @test convert(Integer, Q1f6(1)) === Int8(1) +@test convert(Int, Q1f6(1)) === 1 +@test convert(Integer, Q1f6(1)) === Int8(1) end @testset "Floating-point conversions" begin - @test isa(float(one(Fixed{Int8,6})), Float32) - @test isa(float(one(Fixed{Int32,18})), Float64) - @test isa(float(one(Fixed{Int32,25})), Float64) +@test isa(float(one(Fixed{Int8,6})), Float32) +@test isa(float(one(Fixed{Int32,18})), Float64) +@test isa(float(one(Fixed{Int32,25})), Float64) end @testset "Show" begin - x = Fixed{Int32,5}(0.25) - iob = IOBuffer() - show(iob, x) - str = String(take!(iob)) - @test str == "0.25Q26f5" - @test eval(Meta.parse(str)) == x +x = Fixed{Int32,5}(0.25) +iob = IOBuffer() +show(iob, x) +str = String(take!(iob)) +@test str == "0.25Q26f5" +@test eval(Meta.parse(str)) == x 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 - @test size(a) == (3,5) - end +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 + @test size(a) == (3,5) +end end @testset "realmin" begin - # issue #79 - @test realmin(Q11f4) == Q11f4(0.06) +# issue #79 +@test realmin(Q11f4) == Q11f4(0.06) end @testset "Disambiguation constructors" begin - @test_throws ArgumentError Fixed{Int32,16}('a') - @test_throws InexactError Fixed{Int32,16}(complex(1.0, 1.0)) - @test Fixed{Int32,16}(complex(1.0, 0.0)) == 1 - @test Fixed{Int32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 +@test_throws ArgumentError Fixed{Int32,16}('a') +@test_throws InexactError Fixed{Int32,16}(complex(1.0, 1.0)) +@test Fixed{Int32,16}(complex(1.0, 0.0)) == 1 +@test Fixed{Int32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 end @testset "fractional fixed-point numbers" begin - # test all-fractional fixed-point numbers (issue #104) - for (T, f) in ((Int8, 7), - (Int16, 15), - (Int32, 31), - (Int64, 63)) - tmax = typemax(Fixed{T, f}) - @test tmax == BigInt(typemax(T)) / BigInt(2)^f - tol = (tmax + BigFloat(1.0)) / (sizeof(T) * 8) - for x in range(-1, stop=convert(BigFloat, tmax)-tol, length=50) - @test abs(Fixed{T, f}(x) - x) <= tol - end +# test all-fractional fixed-point numbers (issue #104) +for (T, f) in ((Int8, 7), + (Int16, 15), + (Int32, 31), + (Int64, 63)) + tmax = typemax(Fixed{T, f}) + @test tmax == BigInt(typemax(T)) / BigInt(2)^f + tol = (tmax + BigFloat(1.0)) / (sizeof(T) * 8) + for x in range(-1, stop=convert(BigFloat, tmax)-tol, length=50) + @test abs(Fixed{T, f}(x) - x) <= tol end end +end diff --git a/test/normed.jl b/test/normed.jl index 1dc0e64a..4df6c5f1 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -1,162 +1,161 @@ using FixedPointNumbers, Compat.Test @testset "reinterpret" begin - @test reinterpret(N0f8, 0xa2).i === 0xa2 - @test reinterpret(N6f10, 0x1fa2).i === 0x1fa2 - @test reinterpret(N4f12, 0x1fa2).i === 0x1fa2 - @test reinterpret(N2f14, 0x1fa2).i === 0x1fa2 - @test reinterpret(N0f16, 0x1fa2).i === 0x1fa2 - - @test reinterpret(reinterpret(N0f8, 0xa2)) === 0xa2 - @test reinterpret(reinterpret(N6f10, 0x00a2)) === 0x00a2 - @test reinterpret(reinterpret(N4f12, 0x00a2)) === 0x00a2 - @test reinterpret(reinterpret(N2f14, 0x00a2)) === 0x00a2 - @test reinterpret(reinterpret(N0f16, 0x00a2)) === 0x00a2 - - @test 0.635N0f8 == N0f8(0.635) - @test 0.635N6f10 == N6f10(0.635) - @test 0.635N4f12 == N4f12(0.635) - @test 0.635N2f14 == N2f14(0.635) - @test 0.635N0f16 == N0f16(0.635) - - @test N0f8(1.0) == reinterpret(N0f8, 0xff) - @test N0f8(0.5) == reinterpret(N0f8, 0x80) - @test N2f14(1.0) == reinterpret(N2f14, 0x3fff) - v = N4f12.([2]) - @test v == N4f12[reinterpret(N4f12, 0x1ffe)] - @test isa(v, Vector{N4f12}) +@test reinterpret(N0f8, 0xa2).i === 0xa2 +@test reinterpret(N6f10, 0x1fa2).i === 0x1fa2 +@test reinterpret(N4f12, 0x1fa2).i === 0x1fa2 +@test reinterpret(N2f14, 0x1fa2).i === 0x1fa2 +@test reinterpret(N0f16, 0x1fa2).i === 0x1fa2 + +@test reinterpret(reinterpret(N0f8, 0xa2)) === 0xa2 +@test reinterpret(reinterpret(N6f10, 0x00a2)) === 0x00a2 +@test reinterpret(reinterpret(N4f12, 0x00a2)) === 0x00a2 +@test reinterpret(reinterpret(N2f14, 0x00a2)) === 0x00a2 +@test reinterpret(reinterpret(N0f16, 0x00a2)) === 0x00a2 + +@test 0.635N0f8 == N0f8(0.635) +@test 0.635N6f10 == N6f10(0.635) +@test 0.635N4f12 == N4f12(0.635) +@test 0.635N2f14 == N2f14(0.635) +@test 0.635N0f16 == N0f16(0.635) + +@test N0f8(1.0) == reinterpret(N0f8, 0xff) +@test N0f8(0.5) == reinterpret(N0f8, 0x80) +@test N2f14(1.0) == reinterpret(N2f14, 0x3fff) +v = N4f12.([2]) +@test v == N4f12[reinterpret(N4f12, 0x1ffe)] +@test isa(v, Vector{N4f12}) end UF2 = (Normed{UInt32,16}, Normed{UInt64,3}, Normed{UInt64,51}, Normed{UInt128,7}, Normed{UInt128,51}) @testset "limits and identities" begin - - for T in (FixedPointNumbers.UF..., UF2...) - @test zero(T) == 0 - @test one(T) == 1 - @test one(T) * one(T) == one(T) - @test typemin(T) == 0 - @test realmin(T) == eps(T) - @test eps(zero(T)) == eps(typemax(T)) - @test sizeof(T) == sizeof(FixedPointNumbers.rawtype(T)) - end - @test typemax(N0f8) == 1 - @test typemax(N6f10) == typemax(UInt16)//(2^10-1) - @test typemax(N4f12) == typemax(UInt16)//(2^12-1) - @test typemax(N2f14) == typemax(UInt16)//(2^14-1) - @test typemax(N0f16) == 1 - @test typemax(N6f10) == typemax(UInt16) // (2^10-1) - @test typemax(N4f12) == typemax(UInt16) // (2^12-1) - @test typemax(N2f14) == typemax(UInt16) // (2^14-1) - @test typemax(Normed{UInt32,16}) == typemax(UInt32) // (2^16-1) - @test typemax(Normed{UInt64,3}) == typemax(UInt64) // (2^3-1) - @test typemax(Normed{UInt128,7}) == typemax(UInt128) // (2^7-1) - @test typemax(Normed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-1) +for T in (FixedPointNumbers.UF..., UF2...) + @test zero(T) == 0 + @test one(T) == 1 + @test one(T) * one(T) == one(T) + @test typemin(T) == 0 + @test realmin(T) == eps(T) + @test eps(zero(T)) == eps(typemax(T)) + @test sizeof(T) == sizeof(FixedPointNumbers.rawtype(T)) +end +@test typemax(N0f8) == 1 +@test typemax(N6f10) == typemax(UInt16)//(2^10-1) +@test typemax(N4f12) == typemax(UInt16)//(2^12-1) +@test typemax(N2f14) == typemax(UInt16)//(2^14-1) +@test typemax(N0f16) == 1 +@test typemax(N6f10) == typemax(UInt16) // (2^10-1) +@test typemax(N4f12) == typemax(UInt16) // (2^12-1) +@test typemax(N2f14) == typemax(UInt16) // (2^14-1) +@test typemax(Normed{UInt32,16}) == typemax(UInt32) // (2^16-1) +@test typemax(Normed{UInt64,3}) == typemax(UInt64) // (2^3-1) +@test typemax(Normed{UInt128,7}) == typemax(UInt128) // (2^7-1) +@test typemax(Normed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-1) end @testset "inexactness" begin - # TODO: change back to InexactError when it allows message strings - @test_throws ArgumentError N0f8(2) - @test_throws ArgumentError N0f8(255) - @test_throws ArgumentError N0f8(0xff) - @test_throws ArgumentError N0f16(2) - @test_throws ArgumentError N0f16(0xff) - @test_throws ArgumentError N0f16(0xffff) - @test_throws ArgumentError convert(N0f8, typemax(N6f10)) - @test_throws ArgumentError convert(N0f16, typemax(N6f10)) - @test_throws ArgumentError convert(Normed{UInt128,100}, 10^9) - @test_throws ArgumentError convert(Normed{UInt128,100}, 10.0^9) +# TODO: change back to InexactError when it allows message strings +@test_throws ArgumentError N0f8(2) +@test_throws ArgumentError N0f8(255) +@test_throws ArgumentError N0f8(0xff) +@test_throws ArgumentError N0f16(2) +@test_throws ArgumentError N0f16(0xff) +@test_throws ArgumentError N0f16(0xffff) +@test_throws ArgumentError convert(N0f8, typemax(N6f10)) +@test_throws ArgumentError convert(N0f16, typemax(N6f10)) +@test_throws ArgumentError convert(Normed{UInt128,100}, 10^9) +@test_throws ArgumentError convert(Normed{UInt128,100}, 10.0^9) end @testset "conversion" begin - x = N0f8(0.5) - @test convert(N0f8, x) === x - @test isfinite(x) == true - @test isnan(x) == false - @test isinf(x) == false - - @test convert(N0f8, 1.1/typemax(UInt8)) == eps(N0f8) - @test convert(N6f10, 1.1/typemax(UInt16)*64) == eps(N6f10) - @test convert(N4f12, 1.1/typemax(UInt16)*16) == eps(N4f12) - @test convert(N2f14, 1.1/typemax(UInt16)*4) == eps(N2f14) - @test convert(N0f16, 1.1/typemax(UInt16)) == eps(N0f16) - @test convert(Normed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(Normed{UInt32,16}) - @test convert(Normed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(Normed{UInt64,3}) - @test convert(Normed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(Normed{UInt128,7}) - - @test convert(N0f8, 1.1f0/typemax(UInt8)) == eps(N0f8) - - @test convert(Float64, eps(N0f8)) == 1/typemax(UInt8) - @test convert(Float32, eps(N0f8)) == 1.0f0/typemax(UInt8) - @test convert(BigFloat, eps(N0f8)) == BigFloat(1)/typemax(UInt8) - for T in (FixedPointNumbers.UF..., UF2...) - @test convert(Bool, zero(T)) == false - @test convert(Bool, one(T)) == true - @test convert(Bool, convert(T, 0.2)) == true - @test convert(Int, one(T)) == 1 - @test convert(Integer, one(T)) == 1 - @test convert(Rational, one(T)) == 1 - end - @test convert(Rational, convert(N0f8, 0.5)) == 0x80//0xff - @test convert(N0f16, one(N0f8)) === one(N0f16) - @test convert(N0f16, N0f8(0.5)).i === 0x8080 - @test convert(Normed{UInt16,7}, Normed{UInt8,7}(0.504)) === Normed{UInt16,7}(0.504) +x = N0f8(0.5) +@test convert(N0f8, x) === x +@test isfinite(x) == true +@test isnan(x) == false +@test isinf(x) == false + +@test convert(N0f8, 1.1/typemax(UInt8)) == eps(N0f8) +@test convert(N6f10, 1.1/typemax(UInt16)*64) == eps(N6f10) +@test convert(N4f12, 1.1/typemax(UInt16)*16) == eps(N4f12) +@test convert(N2f14, 1.1/typemax(UInt16)*4) == eps(N2f14) +@test convert(N0f16, 1.1/typemax(UInt16)) == eps(N0f16) +@test convert(Normed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(Normed{UInt32,16}) +@test convert(Normed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(Normed{UInt64,3}) +@test convert(Normed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(Normed{UInt128,7}) + +@test convert(N0f8, 1.1f0/typemax(UInt8)) == eps(N0f8) + +@test convert(Float64, eps(N0f8)) == 1/typemax(UInt8) +@test convert(Float32, eps(N0f8)) == 1.0f0/typemax(UInt8) +@test convert(BigFloat, eps(N0f8)) == BigFloat(1)/typemax(UInt8) +for T in (FixedPointNumbers.UF..., UF2...) + @test convert(Bool, zero(T)) == false + @test convert(Bool, one(T)) == true + @test convert(Bool, convert(T, 0.2)) == true + @test convert(Int, one(T)) == 1 + @test convert(Integer, one(T)) == 1 + @test convert(Rational, one(T)) == 1 +end +@test convert(Rational, convert(N0f8, 0.5)) == 0x80//0xff +@test convert(N0f16, one(N0f8)) === one(N0f16) +@test convert(N0f16, N0f8(0.5)).i === 0x8080 +@test convert(Normed{UInt16,7}, Normed{UInt8,7}(0.504)) === Normed{UInt16,7}(0.504) end @testset "modulus" begin - @test N0f8(0.2) % N0f8 === N0f8(0.2) - @test N2f14(1.2) % N0f16 === N0f16(0.20002) - @test N2f14(1.2) % N0f8 === N0f8(0.196) +@test N0f8(0.2) % N0f8 === N0f8(0.2) +@test N2f14(1.2) % N0f16 === N0f16(0.20002) +@test N2f14(1.2) % N0f8 === N0f8(0.196) - for i = 0.0:0.1:1.0 - @test i % N0f8 === N0f8(i) - end - @test ( 1.5 % N0f8).i == round(Int, 1.5*255) % UInt8 - @test (-0.3 % N0f8).i == round(Int, -0.3*255) % UInt8 +for i = 0.0:0.1:1.0 + @test i % N0f8 === N0f8(i) +end +@test ( 1.5 % N0f8).i == round(Int, 1.5*255) % UInt8 +@test (-0.3 % N0f8).i == round(Int, -0.3*255) % UInt8 - for i = 0.0:0.1:64.0 - @test i % N6f10 === N6f10(i) - end - @test (65.2 % N6f10).i == round(Int, 65.2*1023) % UInt16 - @test (-0.3 % N6f10).i == round(Int, -0.3*1023) % UInt16 +for i = 0.0:0.1:64.0 + @test i % N6f10 === N6f10(i) +end +@test (65.2 % N6f10).i == round(Int, 65.2*1023) % UInt16 +@test (-0.3 % N6f10).i == round(Int, -0.3*1023) % UInt16 - @test 1 % N0f8 == 1 - @test 2 % N0f8 == N0f8(0.996) +@test 1 % N0f8 == 1 +@test 2 % N0f8 == N0f8(0.996) end @testset "bitwise" begin - x = N0f8(0b01010001, 0) - @test ~x == N0f8(0b10101110, 0) - @test -x == reinterpret(N0f8, 0xaf) +x = N0f8(0b01010001, 0) +@test ~x == N0f8(0b10101110, 0) +@test -x == reinterpret(N0f8, 0xaf) end @testset "float" begin - @test isa(float(one(Normed{UInt8,7})), Float32) - @test isa(float(one(Normed{UInt32,18})), Float64) - @test isa(float(one(Normed{UInt32,25})), Float64) +@test isa(float(one(Normed{UInt8,7})), Float32) +@test isa(float(one(Normed{UInt32,18})), Float64) +@test isa(float(one(Normed{UInt32,25})), Float64) end @testset "arithmetic" begin - for T in (FixedPointNumbers.UF..., UF2...) - x = T(0x10,0) - y = T(0x25,0) - fx = float(x) - fy = float(y) - @test y > x - @test y != x - @test typeof(x+y) == T - @test typeof((x+y)-y) == T - @test typeof(x*y) == T - @test typeof(x/y) == T - @test (x+y) ≈ T(0x35,0) - @test ((x+y)-x) ≈ fy - @test ((x-y)+y) ≈ fx - @test (x*y) ≈ convert(T, fx*fy) - @test (x/y) ≈ convert(T, fx/fy) - @test (x^2) ≈ convert(T, fx^2) - @test (x^2.1f0) ≈ fx^2.1f0 - @test (x^2.1) ≈ convert(Float64, x)^2.1 - end +for T in (FixedPointNumbers.UF..., UF2...) + x = T(0x10,0) + y = T(0x25,0) + fx = float(x) + fy = float(y) + @test y > x + @test y != x + @test typeof(x+y) == T + @test typeof((x+y)-y) == T + @test typeof(x*y) == T + @test typeof(x/y) == T + @test (x+y) ≈ T(0x35,0) + @test ((x+y)-x) ≈ fy + @test ((x-y)+y) ≈ fx + @test (x*y) ≈ convert(T, fx*fy) + @test (x/y) ≈ convert(T, fx/fy) + @test (x^2) ≈ convert(T, fx^2) + @test (x^2.1f0) ≈ fx^2.1f0 + @test (x^2.1) ≈ convert(Float64, x)^2.1 +end end function testtrunc(inc::T) where {T} @@ -192,9 +191,9 @@ function testtrunc(inc::T) where {T} end @testset "trunc" begin - for T in (FixedPointNumbers.UF..., UF2...) - testtrunc(eps(T)) - end +for T in (FixedPointNumbers.UF..., UF2...) + testtrunc(eps(T)) +end end function testapprox(::Type{T}) where {T} @@ -207,71 +206,71 @@ function testapprox(::Type{T}) where {T} end @testset "approx" begin - for T in FixedPointNumbers.UF - testapprox(T) - end +for T in FixedPointNumbers.UF + testapprox(T) +end end @testset "low-level arithmetic" begin - @test !(N0f8(0.5) < N0f8(0.5)) - @test N0f8(0.5) <= N0f8(0.5) - - @test div(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 - @test div(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 7 - @test Base.fld1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 - @test Base.fld1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 8 - @test mod(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 0 - @test mod(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) - @test mod1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x02) - @test mod1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) - @test bswap(N0f8(0.5)) === N0f8(0.5) - @test bswap(N0f16(0.5)) === reinterpret(N0f16, 0x0080) - @test minmax(N0f8(0.8), N0f8(0.2)) === (N0f8(0.2), N0f8(0.8)) - - r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48)) - @test length(r) == 48 +@test !(N0f8(0.5) < N0f8(0.5)) +@test N0f8(0.5) <= N0f8(0.5) + +@test div(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 +@test div(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == fld(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 7 +@test Base.fld1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 8 +@test Base.fld1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == 8 +@test mod(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == 0 +@test mod(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == rem(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) +@test mod1(reinterpret(N0f8, 0x10), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x02) +@test mod1(reinterpret(N0f8, 0x0f), reinterpret(N0f8, 0x02)) == reinterpret(N0f8, 0x01) +@test bswap(N0f8(0.5)) === N0f8(0.5) +@test bswap(N0f16(0.5)) === reinterpret(N0f16, 0x0080) +@test minmax(N0f8(0.8), N0f8(0.2)) === (N0f8(0.2), N0f8(0.8)) + +r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48)) +@test length(r) == 48 end @testset "step range" begin - counter = 0 - for x in N0f8(0):eps(N0f8):N0f8(1) - counter += 1 - end - @test counter == 256 +counter = 0 +for x in N0f8(0):eps(N0f8):N0f8(1) + counter += 1 +end +@test counter == 256 end @testset "Promotion within Normed" begin - @test @inferred(promote(N0f8(0.2), N0f8(0.8))) === - (N0f8(0.2), N0f8(0.8)) - @test @inferred(promote(Normed{UInt16,3}(0.2), Normed{UInt8,3}(0.86))) === - (Normed{UInt16,3}(0.2), Normed{UInt16,3}(0.86)) - @test @inferred(promote(Normed{UInt8,7}(0.197), Normed{UInt8,4}(0.8))) === - (Normed{UInt16,7}(0.197), Normed{UInt16,7}(0.8)) - - @test Normed{UInt16,16}(1) == Normed{UInt8,8}(1) - @test Normed{UInt16,16}(0.2) == Normed{UInt8,8}(0.2) - @test Normed{UInt16,8}(1) == Normed{UInt8,8}(1) - @test Normed{UInt16,8}(0.2) == Normed{UInt8,8}(0.2) - @test Normed{UInt16,16}(1) == Normed{UInt8,6}(1) - @test Normed{UInt16,16}(0.20635) == Normed{UInt8,6}(0.20635) - @test Normed{UInt16,4}(1) == Normed{UInt8,6}(1) - @test Normed{UInt16,4}(0.2) == Normed{UInt8,6}(0.2) - - @test promote_type(N0f8,Float32,Int) == Float32 - @test promote_type(N0f8,Int,Float32) == Float32 - @test promote_type(Int,N0f8,Float32) == Float32 - @test promote_type(Int,Float32,N0f8) == Float32 - @test promote_type(Float32,Int,N0f8) == Float32 - @test promote_type(Float32,N0f8,Int) == Float32 +@test @inferred(promote(N0f8(0.2), N0f8(0.8))) === + (N0f8(0.2), N0f8(0.8)) +@test @inferred(promote(Normed{UInt16,3}(0.2), Normed{UInt8,3}(0.86))) === + (Normed{UInt16,3}(0.2), Normed{UInt16,3}(0.86)) +@test @inferred(promote(Normed{UInt8,7}(0.197), Normed{UInt8,4}(0.8))) === + (Normed{UInt16,7}(0.197), Normed{UInt16,7}(0.8)) + +@test Normed{UInt16,16}(1) == Normed{UInt8,8}(1) +@test Normed{UInt16,16}(0.2) == Normed{UInt8,8}(0.2) +@test Normed{UInt16,8}(1) == Normed{UInt8,8}(1) +@test Normed{UInt16,8}(0.2) == Normed{UInt8,8}(0.2) +@test Normed{UInt16,16}(1) == Normed{UInt8,6}(1) +@test Normed{UInt16,16}(0.20635) == Normed{UInt8,6}(0.20635) +@test Normed{UInt16,4}(1) == Normed{UInt8,6}(1) +@test Normed{UInt16,4}(0.2) == Normed{UInt8,6}(0.2) + +@test promote_type(N0f8,Float32,Int) == Float32 +@test promote_type(N0f8,Int,Float32) == Float32 +@test promote_type(Int,N0f8,Float32) == Float32 +@test promote_type(Int,Float32,N0f8) == Float32 +@test promote_type(Float32,Int,N0f8) == Float32 +@test promote_type(Float32,N0f8,Int) == Float32 end @testset "show" begin - x = reinterpret(N0f8, 0xaa) - iob = IOBuffer() - show(iob, x) - str = String(take!(iob)) - @test str == "0.667N0f8" - @test eval(Meta.parse(str)) == x +x = reinterpret(N0f8, 0xaa) +iob = IOBuffer() +show(iob, x) +str = String(take!(iob)) +@test str == "0.667N0f8" +@test eval(Meta.parse(str)) == x end # scaledual @@ -284,70 +283,70 @@ function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number) end @testset "scaledual" begin - a = rand(UInt8, 10) - rfloat = similar(a, Float32) - rfixed = similar(rfloat) - af8 = reinterpret(N0f8, a) - - b = 0.5 - bd, eld = scaledual(b, af8[1]) - @assert b*a[1] == bd*eld - - b, ad = scaledual(0.5, a) - @test b == 0.5 - @test ad == a - b, ad = scaledual(0.5, ad) - generic_scale!(rfloat, a, 0.5) - generic_scale!(rfixed, ad, b) - @test rfloat == rfixed +a = rand(UInt8, 10) +rfloat = similar(a, Float32) +rfixed = similar(rfloat) +af8 = reinterpret(N0f8, a) + +b = 0.5 +bd, eld = scaledual(b, af8[1]) +@assert b*a[1] == bd*eld + +b, ad = scaledual(0.5, a) +@test b == 0.5 +@test ad == a +b, ad = scaledual(0.5, ad) +generic_scale!(rfloat, a, 0.5) +generic_scale!(rfixed, ad, b) +@test rfloat == rfixed end @testset "reductions" begin - a = N0f8[reinterpret(N0f8, 0xff), reinterpret(N0f8, 0xff)] - @test sum(a) == 2.0 - @test sum(a, dims=1) == [2.0] - - a = N2f14[3.2, 2.4] - acmp = convert(Float64, a[1])*convert(Float64, a[2]) - @test prod(a) == acmp - @test prod(a, dims=1) == [acmp] +a = N0f8[reinterpret(N0f8, 0xff), reinterpret(N0f8, 0xff)] +@test sum(a) == 2.0 +@test sum(a, dims=1) == [2.0] + +a = N2f14[3.2, 2.4] +acmp = convert(Float64, a[1])*convert(Float64, a[2]) +@test prod(a) == acmp +@test prod(a, dims=1) == [acmp] end @testset "convert" begin - x = N0f8(0.3) - for T in (Float16, Float32, Float64, BigFloat) - y = convert(T, x) - @test isa(y, T) - end +x = N0f8(0.3) +for T in (Float16, Float32, Float64, BigFloat) + y = convert(T, x) + @test isa(y, T) +end end @testset "rand" begin - for T in (Normed{UInt8,8}, Normed{UInt8,6}, - Normed{UInt16,16}, Normed{UInt16,14}, - Normed{UInt32,32}, Normed{UInt32,30}, - Normed{UInt64,64}, Normed{UInt64,62}) - a = rand(T) - @test isa(a, T) - a = rand(T, (3, 5)) - @test ndims(a) == 2 && eltype(a) == T - @test size(a) == (3,5) - end +for T in (Normed{UInt8,8}, Normed{UInt8,6}, + Normed{UInt16,16}, Normed{UInt16,14}, + Normed{UInt32,32}, Normed{UInt32,30}, + Normed{UInt64,64}, Normed{UInt64,62}) + a = rand(T) + @test isa(a, T) + a = rand(T, (3, 5)) + @test ndims(a) == 2 && eltype(a) == T + @test size(a) == (3,5) +end end @testset "Overflow with Float16" begin - @test N0f16(Float16(1.0)) === N0f16(1.0) - @test Float16(1.0) % N0f16 === N0f16(1.0) +@test N0f16(Float16(1.0)) === N0f16(1.0) +@test Float16(1.0) % N0f16 === N0f16(1.0) end @testset "summary" begin - a = N0f8[0.2, 0.4] - @test summary(a) == "2-element Array{N0f8,1} with eltype Normed{UInt8,8}" - @test summary(view(a, 1:2)) == "2-element view(::Array{N0f8,1}, 1:2) with eltype Normed{UInt8,8}" +a = N0f8[0.2, 0.4] +@test summary(a) == "2-element Array{N0f8,1} with eltype Normed{UInt8,8}" +@test summary(view(a, 1:2)) == "2-element view(::Array{N0f8,1}, 1:2) with eltype Normed{UInt8,8}" end @testset "disambiguation constructors" begin - @test_throws ArgumentError Normed{UInt32,16}('a') - @test_throws InexactError Normed{UInt32,16}(complex(1.0, 1.0)) - @test Normed{UInt32,16}(complex(1.0, 0.0)) == 1 - @test Normed{UInt32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 +@test_throws ArgumentError Normed{UInt32,16}('a') +@test_throws InexactError Normed{UInt32,16}(complex(1.0, 1.0)) +@test Normed{UInt32,16}(complex(1.0, 0.0)) == 1 +@test Normed{UInt32,16}(Base.TwicePrecision(1.0, 0.0)) == 1 end From a14a14e12a0d4a8ea13d9506cf2f67de8ff0c1d0 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Fri, 8 Jun 2018 16:47:31 -0400 Subject: [PATCH 04/10] remove Compat references --- test/fixed.jl | 2 +- test/normed.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixed.jl b/test/fixed.jl index 8c0012b2..9c7bd7c0 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -1,4 +1,4 @@ -using FixedPointNumbers, Compat.Test +using FixedPointNumbers, Test function test_op(fun::F, ::Type{T}, fx, fy, fxf, fyf, tol) where {F,T} # Make sure that the result is representable diff --git a/test/normed.jl b/test/normed.jl index 4df6c5f1..3f73fc33 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -1,4 +1,4 @@ -using FixedPointNumbers, Compat.Test +using FixedPointNumbers, Test @testset "reinterpret" begin @test reinterpret(N0f8, 0xa2).i === 0xa2 From 41b79ff50183b649e3e4ceeac93472632a604d7e Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Sat, 9 Jun 2018 14:29:38 -0400 Subject: [PATCH 05/10] trivial change to bump travis now that nightlies work again --- test/runtests.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 07b52040..53f53ca6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,6 @@ using FixedPointNumbers, Test @testset "normed" begin include("normed.jl") end - @testset "fixed" begin include("fixed.jl") end From a7fa49d054f4f10d778871ab5d8c322a4e24b6fa Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Sat, 9 Jun 2018 14:32:50 -0400 Subject: [PATCH 06/10] fix deprecations in CI scripts themselves --- .travis.yml | 6 +++--- appveyor.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ae6fb61..712452e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ notifications: email: false script: - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - julia -e 'Pkg.clone(pwd()); Pkg.build("FixedPointNumbers")' - - julia -e 'Pkg.test("FixedPointNumbers"; coverage=true)' + - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("FixedPointNumbers")' + - julia -e 'using Pkg; Pkg.test("FixedPointNumbers"; coverage=true)' after_success: # push coverage results to Codecov - - julia -e 'cd(Pkg.dir("FixedPointNumbers")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' + - julia -e 'using Pkg; cd(Pkg.dir("FixedPointNumbers")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' diff --git a/appveyor.yml b/appveyor.yml index d9d06300..720bb89f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,7 +29,7 @@ build_script: # Need to convert from shallow to complete for Pkg.clone to work - IF EXIST .git\shallow (git fetch --unshallow) - C:\projects\julia\bin\julia -e "versioninfo(); - Pkg.clone(pwd(), \"FixedPointNumbers\"); Pkg.build(\"FixedPointNumbers\")" + using Pkg; Pkg.clone(pwd(), \"FixedPointNumbers\"); Pkg.build(\"FixedPointNumbers\")" test_script: - - C:\projects\julia\bin\julia -e "Pkg.test(\"FixedPointNumbers\")" + - C:\projects\julia\bin\julia -e "using Pkg; Pkg.test(\"FixedPointNumbers\")" From 4e110c81ccf9d96d73acd407af3977a1a94aa7be Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Sun, 10 Jun 2018 13:15:48 -0400 Subject: [PATCH 07/10] require 0.7-alpha --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 4aa321c1..cdbb2dc1 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1 @@ -julia 0.7- +julia 0.7-alpha From 0e3b6490b87f257a217e217623c559e998baeac7 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Sun, 10 Jun 2018 13:24:15 -0400 Subject: [PATCH 08/10] remove deprecations --- src/FixedPointNumbers.jl | 1 + src/deprecations.jl | 49 ---------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 9bb14d27..69e2329a 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -126,6 +126,7 @@ end include("fixed.jl") include("normed.jl") include("deprecations.jl") +const UF = (N0f8, N6f10, N4f12, N2f14, N0f16) eps(::Type{T}) where {T <: FixedPoint} = T(oneunit(rawtype(T)),0) eps(::T) where {T <: FixedPoint} = eps(T) diff --git a/src/deprecations.jl b/src/deprecations.jl index 8003cb7b..b768d486 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -1,50 +1 @@ import Base.@deprecate_binding - -@deprecate_binding Fixed16 Q15f16 -@deprecate_binding UFixed8 N0f8 -@deprecate_binding UFixed10 N6f10 -@deprecate_binding UFixed12 N4f12 -@deprecate_binding UFixed14 N2f14 -@deprecate_binding UFixed16 N0f16 - -@deprecate_binding UfixedBase Normed -@deprecate_binding Ufixed Normed -@deprecate_binding UFixed Normed -@deprecate_binding Ufixed8 N0f8 -@deprecate_binding Ufixed10 N6f10 -@deprecate_binding Ufixed12 N4f12 -@deprecate_binding Ufixed14 N2f14 -@deprecate_binding Ufixed16 N0f16 - -@deprecate_binding Fixed32 Q15f16 - -const UF = (N0f8, N6f10, N4f12, N2f14, N0f16) - -@deprecate Fixed(x::Real) convert(Fixed{Int32, 16}, x) - -@deprecate ufixed8(x) N0f8(x) -@deprecate ufixed10(x) N6f10(x) -@deprecate ufixed12(x) N4f12(x) -@deprecate ufixed14(x) N2f14(x) -@deprecate ufixed16(x) N0f16(x) - -## The next lines mimic the floating-point literal syntax "3.2f0" -# construction using a UInt, i.e., 0xccuf8 -struct NormedConstructor{T,f} end -function *(n::Integer, ::NormedConstructor{T,f}) where {T,f} - i = 8*sizeof(T)-f - io = IOBuffer() - show(io, n) - nstr = String(take!(io)) - cstr = typeof(n) == T ? nstr : "convert($T, $nstr)" - Base.depwarn("$(nstr)uf$f is deprecated, please use reinterpret(N$(i)f$f, $cstr) instead", :*) - reinterpret(Normed{T,f}, convert(T, n)) -end -const uf8 = NormedConstructor{UInt8,8}() -const uf10 = NormedConstructor{UInt16,10}() -const uf12 = NormedConstructor{UInt16,12}() -const uf14 = NormedConstructor{UInt16,14}() -const uf16 = NormedConstructor{UInt16,16}() - -@deprecate_binding UfixedConstructor NormedConstructor -@deprecate_binding UFixedConstructor NormedConstructor From 59f22cbd67dc334bf412456ece7b82420bb3cd98 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Sun, 10 Jun 2018 13:27:27 -0400 Subject: [PATCH 09/10] remove stale exports --- src/FixedPointNumbers.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 69e2329a..b4702691 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -27,12 +27,6 @@ export Normed, # "special" typealiases # Q and U typealiases are exported in separate source files -# literal constructor constants - uf8, - uf10, - uf12, - uf14, - uf16, # Functions scaledual From a4ee3042839d9935c0f26f1606a3b0648b0de20c Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Tue, 12 Jun 2018 22:27:55 -0400 Subject: [PATCH 10/10] change all `convert` methods to constructors --- src/FixedPointNumbers.jl | 8 ++++---- src/fixed.jl | 38 ++++++++++++++++++-------------------- src/normed.jl | 36 +++++++++++++++++------------------- test/fixed.jl | 6 +++--- test/normed.jl | 2 +- 5 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index b4702691..9a8f6c0c 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -142,12 +142,12 @@ if isdefined(Base, :r_promote) Base.reducedim_initarray(A, region, oneunit(Treduce)) else # Julia v0.7 - Base.add_sum(x::FixedPoint, y::FixedPoint) = convert(Treduce, x) + convert(Treduce, y) + Base.add_sum(x::FixedPoint, y::FixedPoint) = Treduce(x) + Treduce(y) Base.reduce_empty(::typeof(Base.add_sum), ::Type{F}) where {F<:FixedPoint} = zero(Treduce) - Base.reduce_first(::typeof(Base.add_sum), x::FixedPoint) = convert(Treduce, x) - Base.mul_prod(x::FixedPoint, y::FixedPoint) = convert(Treduce, x) * convert(Treduce, y) + Base.reduce_first(::typeof(Base.add_sum), x::FixedPoint) = Treduce(x) + Base.mul_prod(x::FixedPoint, y::FixedPoint) = Treduce(x) * Treduce(y) Base.reduce_empty(::typeof(Base.mul_prod), ::Type{F}) where {F<:FixedPoint} = one(Treduce) - Base.reduce_first(::typeof(Base.mul_prod), x::FixedPoint) = convert(Treduce, x) + Base.reduce_first(::typeof(Base.mul_prod), x::FixedPoint) = Treduce(x) end diff --git a/src/fixed.jl b/src/fixed.jl index 5c80cc96..69e043b4 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -5,13 +5,15 @@ 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) - Fixed{T, f}(x) where {T,f} = convert(Fixed{T,f}, x) - Fixed{T, f}(x::Fixed{T,f}) where {T,f} = x - Fixed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Fixed cannot be constructed from a Char")) - Fixed{T, f}(x::Complex) where {T,f} = Fixed{T, f}(convert(real(typeof(x)), x)) - Fixed{T, f}(x::Base.TwicePrecision) where {T,f} = Fixed{T, f}(convert(Float64, x)) end +Fixed{T, f}(x::AbstractChar) where {T,f} = throw(ArgumentError("Fixed cannot be constructed from a Char")) +Fixed{T, f}(x::Complex) where {T,f} = Fixed{T, f}(convert(real(typeof(x)), x)) +Fixed{T, f}(x::Base.TwicePrecision) where {T,f} = Fixed{T, f}(convert(Float64, x)) +Fixed{T,f}(x::Integer) where {T,f} = Fixed{T,f}(round(T, convert(widen1(T),x)<>f) + convert(BigFloat,x.i&(one(widen1(T))<>f) + convert(TF,x.i&(one(widen1(T))<>f) + BigFloat(x.i&(one(widen1(T))<>f) + TF(x.i&(one(widen1(T))<>f) + Integer(x.i>>f) end -function convert(::Type{TI}, x::Fixed{T,f}) where {TI <: Integer,T,f} +function (::Type{TI})(x::Fixed{T,f}) where {TI <: Integer,T,f} isinteger(x) || throw(InexactError()) - convert(TI, x.i>>f) + TI(x.i>>f) end -convert(::Type{TR}, x::Fixed{T,f}) where {TR <: Rational,T,f} = - convert(TR, x.i>>f + (x.i&(1<>f + (x.i&(1<