From 123f99021451e367067b876b0cab9b9f22838b23 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sat, 17 Sep 2016 01:47:29 -0500 Subject: [PATCH 1/6] Compact systematic display of values --- src/FixedPointNumbers.jl | 40 +++++++++++++++++++++++++++------------- src/fixed.jl | 17 +++++++++++++++-- src/ufixed.jl | 18 +++++++++++++++++- test/fixed.jl | 4 ++-- test/ufixed.jl | 8 +++++++- 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index cf5432cf..93aafa7a 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -26,27 +26,50 @@ using Compat # f => Number of Bytes reserved for fractional part abstract FixedPoint{T <: Integer, f} <: Real + +# Printing. These are used to generate type-symbols, so we need them early. +function showtype{X<:FixedPoint}(io::IO, ::Type{X}) + print(io, typechar(X)) + f = nbitsfrac(X) + m = sizeof(X)*8-f-signbits(X) + print(io, m, 'f', f) + io +end +function show{T,f}(io::IO, x::FixedPoint{T,f}) + showcompact(io, x) + showtype(io, typeof(x)) +end +const _log2_10 = 3.321928094887362 +showcompact{T,f}(io::IO, x::FixedPoint{T,f}) = show(io, round(convert(Float64,x), ceil(Int,f/_log2_10))) + export FixedPoint, Fixed, UFixed, +# "special" typealiases Fixed16, UFixed8, + U8, UFixed10, UFixed12, UFixed14, UFixed16, - # literal constructor constants + U16, + # Q and U typealiases are exported in separate source files +# literal constructor constants uf8, uf10, uf12, uf14, uf16, - # Functions +# Functions scaledual reinterpret(x::FixedPoint) = x.i +# construction using the (approximate) intended value, i.e., N0f8 +*{X<:FixedPoint}(x::Real, ::Type{X}) = X(x) + # comparison =={T <: FixedPoint}(x::T, y::T) = x.i == y.i <{T <: FixedPoint}(x::T, y::T) = x.i < y.i @@ -90,6 +113,8 @@ floattype{T<:ShortInts,f}(::Type{FixedPoint{T,f}}) = Float32 floattype{T,f}(::Type{FixedPoint{T,f}}) = Float64 floattype(x::FixedPoint) = floattype(supertype(typeof(x))) +# This IOBuffer is used during module definition to generate typealias names +_iotypealias = IOBuffer() include("fixed.jl") include("ufixed.jl") @@ -141,17 +166,6 @@ scaledual{T<:FixedPoint}(Tdual::Type, x::Union{T,AbstractArray{T}}) = scaledual{Tdual<:Number, T<:FixedPoint}(b::Tdual, x::Union{T,AbstractArray{T}}) = convert(Tdual, b/one(T)), reinterpret(rawtype(T), x) -# printing -function show{T,f}(io::IO, x::FixedPoint{T,f}) - shorttype = typeof(x)<:UFixed ? "UFixed" : "Fixed" - print(io, shorttype, "{", T, ",", f, "}") - print(io, "(") - showcompact(io, x) - print(io, ")") -end -const _log2_10 = 3.321928094887362 -showcompact{T,f}(io::IO, x::FixedPoint{T,f}) = show(io, round(Float64(x), ceil(Int,f/_log2_10))) - @noinline function throw_converterror{T<:FixedPoint}(::Type{T}, x) n = 2^(8*sizeof(T)) bitstring = sizeof(T) == 1 ? "an 8-bit" : "a $(8*sizeof(T))-bit" diff --git a/src/fixed.jl b/src/fixed.jl index fb7a4980..a92a9974 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -9,13 +9,26 @@ immutable Fixed{T <: Signed,f} <: FixedPoint{T, f} Fixed(x) = convert(Fixed{T,f}, x) end -typealias Fixed16 Fixed{Int32, 16} - reinterpret{T<:Signed, f}(::Type{Fixed{T,f}}, x::T) = Fixed{T,f}(x, 0) rawtype{T,f}(::Type{Fixed{T,f}}) = T nbitsfrac{T,f}(::Type{Fixed{T,f}}) = f floattype{T<:Fixed}(::Type{T}) = floattype(supertype(T)) +typechar{X<:Fixed}(::Type{X}) = 'Q' +signbits{X<:Fixed}(::Type{X}) = 1 + +for T in (Int8, Int16, Int32, Int64) + for f in 0:sizeof(T)*8-1 + sym = Symbol(takebuf_string(showtype(_iotypealias, Fixed{T,f}))) + @eval begin + typealias $sym Fixed{$T,$f} + export $sym + end + end +end + +# ASCII typealiases +typealias Fixed16 Fixed{Int32,16} # basic operators -{T,f}(x::Fixed{T,f}) = Fixed{T,f}(-x.i,0) diff --git a/src/ufixed.jl b/src/ufixed.jl index 4772d988..b4cccf71 100644 --- a/src/ufixed.jl +++ b/src/ufixed.jl @@ -12,18 +12,34 @@ end rawtype(x::Number) = rawtype(typeof(x)) nbitsfrac{T,f}(::Type{UFixed{T,f}}) = f floattype{T<:UFixed}(::Type{T}) = floattype(supertype(T)) +typechar{X<:UFixed}(::Type{X}) = 'N' +signbits{X<:UFixed}(::Type{X}) = 0 + +for T in (UInt8, UInt16, UInt32, UInt64) + for f in 0:sizeof(T)*8 + sym = Symbol(takebuf_string(showtype(_iotypealias, UFixed{T,f}))) + @eval begin + typealias $sym UFixed{$T,$f} + export $sym + end + end +end +# ASCII typealiases +typealias U8 UFixed{UInt8,8} typealias UFixed8 UFixed{UInt8,8} typealias UFixed10 UFixed{UInt16,10} typealias UFixed12 UFixed{UInt16,12} typealias UFixed14 UFixed{UInt16,14} typealias UFixed16 UFixed{UInt16,16} +typealias U16 UFixed{UInt16,16} const UF = (UFixed8, UFixed10, UFixed12, UFixed14, UFixed16) reinterpret{T<:Unsigned, f}(::Type{UFixed{T,f}}, x::T) = UFixed{T,f}(x, 0) -# The next lines mimic the floating-point literal syntax "3.2f0" +## The next lines mimic the floating-point literal syntax "3.2f0" +# construction using a UInt, i.e., 0xccuf8 immutable UFixedConstructor{T,f} end *{T,f}(n::Integer, ::UFixedConstructor{T,f}) = UFixed{T,f}(n,0) const uf8 = UFixedConstructor{UInt8,8}() diff --git a/test/fixed.jl b/test/fixed.jl index f3e4d440..a0c588c2 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -107,11 +107,11 @@ end @test isa(float(one(Fixed{Int32,25})), Float64) # Show -x = Fixed{Int32,3}(0.25) +x = Fixed{Int32,5}(0.25) iob = IOBuffer() show(iob, x) str = takebuf_string(iob) -@test startswith(str, "Fixed{Int32,3}(") +@test str == "0.25Q26f5" @test eval(parse(str)) == x for T in (Fixed{Int8,8}, Fixed{Int16,8}, Fixed{Int16,10}, Fixed{Int32,16}) diff --git a/test/ufixed.jl b/test/ufixed.jl index 6c2a3aba..64042c36 100644 --- a/test/ufixed.jl +++ b/test/ufixed.jl @@ -13,6 +13,11 @@ using Compat @test reinterpret(UFixed12, 0x1fa2) == 0x1fa2uf12 @test reinterpret(UFixed14, 0x1fa2) == 0x1fa2uf14 @test reinterpret(UFixed16, 0x1fa2) == 0x1fa2uf16 +@test 0.635N0f8 == UFixed8(0.635) +@test 0.635N6f10 == UFixed10(0.635) +@test 0.635N4f12 == UFixed12(0.635) +@test 0.635N2f14 == UFixed14(0.635) +@test 0.635N0f16 == UFixed16(0.635) @test UFixed8(1.0) == 0xffuf8 @test UFixed8(0.5) == 0x80uf8 @@ -234,7 +239,8 @@ x = 0xaauf8 iob = IOBuffer() show(iob, x) str = takebuf_string(iob) -@test str == "UFixed{UInt8,8}(0.667)" +@test str == "0.667N0f8" +@test eval(parse(str)) == x # scaledual function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number) From f226e62231f53d1411d0c5e4f724e15b756b0f2b Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 11 Oct 2016 10:33:27 -0500 Subject: [PATCH 2/6] Deprecate UFixed8 and friends in favor of N0f8 and friends --- src/FixedPointNumbers.jl | 49 +++++-------- src/deprecations.jl | 32 ++++++--- src/fixed.jl | 3 +- src/ufixed.jl | 15 +--- test/ufixed.jl | 148 +++++++++++++++++++-------------------- 5 files changed, 116 insertions(+), 131 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 93aafa7a..7aea8927 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -27,34 +27,11 @@ using Compat abstract FixedPoint{T <: Integer, f} <: Real -# Printing. These are used to generate type-symbols, so we need them early. -function showtype{X<:FixedPoint}(io::IO, ::Type{X}) - print(io, typechar(X)) - f = nbitsfrac(X) - m = sizeof(X)*8-f-signbits(X) - print(io, m, 'f', f) - io -end -function show{T,f}(io::IO, x::FixedPoint{T,f}) - showcompact(io, x) - showtype(io, typeof(x)) -end -const _log2_10 = 3.321928094887362 -showcompact{T,f}(io::IO, x::FixedPoint{T,f}) = show(io, round(convert(Float64,x), ceil(Int,f/_log2_10))) - export FixedPoint, Fixed, UFixed, # "special" typealiases - Fixed16, - UFixed8, - U8, - UFixed10, - UFixed12, - UFixed14, - UFixed16, - U16, # Q and U typealiases are exported in separate source files # literal constructor constants uf8, @@ -66,6 +43,7 @@ export scaledual reinterpret(x::FixedPoint) = x.i +reinterpret{T,f}(::Type{T}, x::FixedPoint{T,f}) = x.i # construction using the (approximate) intended value, i.e., N0f8 *{X<:FixedPoint}(x::Real, ::Type{X}) = X(x) @@ -116,6 +94,23 @@ floattype(x::FixedPoint) = floattype(supertype(typeof(x))) # This IOBuffer is used during module definition to generate typealias names _iotypealias = IOBuffer() +# Printing. These are used to generate type-symbols, so we need them +# before we include any files. +function showtype{X<:FixedPoint}(io::IO, ::Type{X}) + print(io, typechar(X)) + f = nbitsfrac(X) + m = sizeof(X)*8-f-signbits(X) + print(io, m, 'f', f) + io +end +function show{T,f}(io::IO, x::FixedPoint{T,f}) + showcompact(io, x) + showtype(io, typeof(x)) +end +const _log2_10 = 3.321928094887362 +showcompact{T,f}(io::IO, x::FixedPoint{T,f}) = show(io, round(convert(Float64,x), ceil(Int,f/_log2_10))) + + include("fixed.jl") include("ufixed.jl") include("deprecations.jl") @@ -138,14 +133,6 @@ reducedim_init{T<:FixedPoint}(f::typeof(@functorize(identity)), A::AbstractArray{T}, region) = reducedim_initarray(A, region, one(Treduce)) -# TODO: rewrite this by @generated -for T in tuple(Fixed16, UF...) - R = rawtype(T) - @eval begin - reinterpret(::Type{$R}, x::$T) = x.i - end -end - for f in (:div, :fld, :fld1) @eval begin $f{T<:FixedPoint}(x::T, y::T) = $f(reinterpret(x),reinterpret(y)) diff --git a/src/deprecations.jl b/src/deprecations.jl index 9fe39c37..601d3ade 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -1,22 +1,32 @@ 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 UFixed @deprecate_binding UfixedConstructor UFixedConstructor @deprecate_binding Ufixed UFixed -@deprecate_binding Ufixed8 UFixed8 -@deprecate_binding Ufixed10 UFixed10 -@deprecate_binding Ufixed12 UFixed12 -@deprecate_binding Ufixed14 UFixed14 -@deprecate_binding Ufixed16 UFixed16 +@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_binding Fixed32 Fixed16 @deprecate Fixed(x::Real) convert(Fixed{Int32, 16}, x) -@deprecate ufixed8(x) UFixed8(x) -@deprecate ufixed10(x) UFixed10(x) -@deprecate ufixed12(x) UFixed12(x) -@deprecate ufixed14(x) UFixed14(x) -@deprecate ufixed16(x) UFixed16(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) Compat.@dep_vectorize_1arg Real ufixed8 Compat.@dep_vectorize_1arg Real ufixed10 diff --git a/src/fixed.jl b/src/fixed.jl index a92a9974..87ac160d 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -27,8 +27,7 @@ for T in (Int8, Int16, Int32, Int64) end end -# ASCII typealiases -typealias Fixed16 Fixed{Int32,16} +reinterpret{T<:Signed, f}(::Type{Fixed{T,f}}, x::T) = Fixed{T,f}(x, 0) # basic operators -{T,f}(x::Fixed{T,f}) = Fixed{T,f}(-x.i,0) diff --git a/src/ufixed.jl b/src/ufixed.jl index b4cccf71..5656f0ed 100644 --- a/src/ufixed.jl +++ b/src/ufixed.jl @@ -1,5 +1,5 @@ # UFixed{T,f} maps UInts from 0 to 2^f-1 to the range [0.0, 1.0] -# For example, a UFixed8 maps 0x00 to 0.0 and 0xff to 1.0 +# For example, UFixed{UInt8,8} == N0f8 maps 0x00 to 0.0 and 0xff to 1.0 immutable UFixed{T<:Unsigned,f} <: FixedPoint{T,f} i::T @@ -25,17 +25,6 @@ for T in (UInt8, UInt16, UInt32, UInt64) end end -# ASCII typealiases -typealias U8 UFixed{UInt8,8} -typealias UFixed8 UFixed{UInt8,8} -typealias UFixed10 UFixed{UInt16,10} -typealias UFixed12 UFixed{UInt16,12} -typealias UFixed14 UFixed{UInt16,14} -typealias UFixed16 UFixed{UInt16,16} -typealias U16 UFixed{UInt16,16} - -const UF = (UFixed8, UFixed10, UFixed12, UFixed14, UFixed16) - reinterpret{T<:Unsigned, f}(::Type{UFixed{T,f}}, x::T) = UFixed{T,f}(x, 0) ## The next lines mimic the floating-point literal syntax "3.2f0" @@ -65,7 +54,7 @@ function convert{T,T2,f}(::Type{UFixed{T,f}}, x::UFixed{T2}) (0 <= y) & (y <= typemax(T)) || throw_converterror(U, x) reinterpret(U, _unsafe_trunc(T, y)) end -convert(::Type{UFixed16}, x::UFixed8) = reinterpret(UFixed16, convert(UInt16, 0x0101*reinterpret(x))) +convert(::Type{N0f16}, x::N0f8) = reinterpret(N0f16, convert(UInt16, 0x0101*reinterpret(x))) convert{U<:UFixed}(::Type{U}, x::Real) = _convert(U, rawtype(U), x) function _convert{U<:UFixed,T}(::Type{U}, ::Type{T}, x) y = round(widen1(rawone(U))*x) diff --git a/test/ufixed.jl b/test/ufixed.jl index 64042c36..16755f06 100644 --- a/test/ufixed.jl +++ b/test/ufixed.jl @@ -8,23 +8,23 @@ using Compat @test reinterpret(0xa2uf14) == 0xa2 @test reinterpret(0xa2uf16) == 0xa2 -@test reinterpret(UFixed8, 0xa2) == 0xa2uf8 -@test reinterpret(UFixed10, 0x1fa2) == 0x1fa2uf10 -@test reinterpret(UFixed12, 0x1fa2) == 0x1fa2uf12 -@test reinterpret(UFixed14, 0x1fa2) == 0x1fa2uf14 -@test reinterpret(UFixed16, 0x1fa2) == 0x1fa2uf16 -@test 0.635N0f8 == UFixed8(0.635) -@test 0.635N6f10 == UFixed10(0.635) -@test 0.635N4f12 == UFixed12(0.635) -@test 0.635N2f14 == UFixed14(0.635) -@test 0.635N0f16 == UFixed16(0.635) - -@test UFixed8(1.0) == 0xffuf8 -@test UFixed8(0.5) == 0x80uf8 -@test UFixed14(1.0) == 0x3fffuf14 -v = @compat UFixed12.([2]) -@test v == UFixed12[0x1ffeuf12] -@test isa(v, Vector{UFixed12}) +@test reinterpret(N0f8, 0xa2) == 0xa2uf8 +@test reinterpret(N6f10, 0x1fa2) == 0x1fa2uf10 +@test reinterpret(N4f12, 0x1fa2) == 0x1fa2uf12 +@test reinterpret(N2f14, 0x1fa2) == 0x1fa2uf14 +@test reinterpret(N0f16, 0x1fa2) == 0x1fa2uf16 +@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) == 0xffuf8 +@test N0f8(0.5) == 0x80uf8 +@test N2f14(1.0) == 0x3fffuf14 +v = @compat N4f12.([2]) +@test v == N4f12[0x1ffeuf12] +@test isa(v, Vector{N4f12}) UF2 = (UFixed{UInt32,16}, UFixed{UInt64,3}, UFixed{UInt64,51}, UFixed{UInt128,7}, UFixed{UInt128,51}) @@ -37,50 +37,50 @@ for T in (FixedPointNumbers.UF..., UF2...) @test eps(zero(T)) == eps(typemax(T)) @test sizeof(T) == sizeof(FixedPointNumbers.rawtype(T)) end -@test typemax(UFixed8) == 1 -@test typemax(UFixed10) == typemax(UInt16)//(2^10-1) -@test typemax(UFixed12) == typemax(UInt16)//(2^12-1) -@test typemax(UFixed14) == typemax(UInt16)//(2^14-1) -@test typemax(UFixed16) == 1 -@test typemax(UFixed10) == typemax(UInt16) // (2^10-1) -@test typemax(UFixed12) == typemax(UInt16) // (2^12-1) -@test typemax(UFixed14) == typemax(UInt16) // (2^14-1) +@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(UFixed{UInt32,16}) == typemax(UInt32) // (2^16-1) @test typemax(UFixed{UInt64,3}) == typemax(UInt64) // (2^3-1) @test typemax(UFixed{UInt128,7}) == typemax(UInt128) // (2^7-1) @test typemax(UFixed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-1) # TODO: change back to InexactError when it allows message strings -@test_throws ArgumentError UFixed8(2) -@test_throws ArgumentError UFixed8(255) -@test_throws ArgumentError UFixed8(0xff) -@test_throws ArgumentError UFixed16(2) -@test_throws ArgumentError UFixed16(0xff) -@test_throws ArgumentError UFixed16(0xffff) -@test_throws ArgumentError convert(UFixed8, typemax(UFixed10)) -@test_throws ArgumentError convert(UFixed16, typemax(UFixed10)) +@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(UFixed{UInt128,100}, 10^9) @test_throws ArgumentError convert(UFixed{UInt128,100}, 10.0^9) -x = UFixed8(0.5) +x = N0f8(0.5) @test isfinite(x) == true @test isnan(x) == false @test isinf(x) == false -@test convert(UFixed8, 1.1/typemax(UInt8)) == eps(UFixed8) -@test convert(UFixed10, 1.1/typemax(UInt16)*64) == eps(UFixed10) -@test convert(UFixed12, 1.1/typemax(UInt16)*16) == eps(UFixed12) -@test convert(UFixed14, 1.1/typemax(UInt16)*4) == eps(UFixed14) -@test convert(UFixed16, 1.1/typemax(UInt16)) == eps(UFixed16) +@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(UFixed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(UFixed{UInt32,16}) @test convert(UFixed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(UFixed{UInt64,3}) @test convert(UFixed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(UFixed{UInt128,7}) -@test convert(UFixed8, 1.1f0/typemax(UInt8)) == eps(UFixed8) +@test convert(N0f8, 1.1f0/typemax(UInt8)) == eps(N0f8) -@test convert(Float64, eps(UFixed8)) == 1/typemax(UInt8) -@test convert(Float32, eps(UFixed8)) == 1.0f0/typemax(UInt8) -@test convert(BigFloat, eps(UFixed8)) == BigFloat(1)/typemax(UInt8) +@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 @@ -88,32 +88,32 @@ for T in (FixedPointNumbers.UF..., UF2...) @test convert(Int, one(T)) == 1 @test convert(Rational, one(T)) == 1 end -@test convert(Rational, convert(UFixed8, 0.5)) == 0x80//0xff -@test convert(UFixed16, one(UFixed8)) === one(UFixed16) -@test convert(UFixed16, UFixed8(0.5)).i === 0x8080 +@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(UFixed{UInt16,7}, UFixed{UInt8,7}(0.504)) === UFixed{UInt16,7}(0.504) -@test UFixed8(0.2) % UFixed8 === UFixed8(0.2) -@test UFixed14(1.2) % UFixed16 === UFixed16(0.20002) -@test UFixed14(1.2) % UFixed8 === UFixed8(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 % UFixed8 === UFixed8(i) + @test i % N0f8 === N0f8(i) end -@test ( 1.5 % UFixed8).i == round(Int, 1.5*255) % UInt8 -@test (-0.3 % UFixed8).i == round(Int, -0.3*255) % UInt8 +@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 % UFixed10 === UFixed10(i) + @test i % N6f10 === N6f10(i) end -@test (65.2 % UFixed10).i == round(Int, 65.2*1023) % UInt16 -@test (-0.3 % UFixed10).i == round(Int, -0.3*1023) % UInt16 +@test (65.2 % N6f10).i == round(Int, 65.2*1023) % UInt16 +@test (-0.3 % N6f10).i == round(Int, -0.3*1023) % UInt16 -@test 1 % UFixed8 == 1 -@test 2 % UFixed8 == UFixed8(0.996) +@test 1 % N0f8 == 1 +@test 2 % N0f8 == N0f8(0.996) -x = UFixed8(0b01010001, 0) -@test ~x == UFixed8(0b10101110, 0) +x = N0f8(0b01010001, 0) +@test ~x == N0f8(0b10101110, 0) @test -x == 0xafuf8 @test isa(float(one(UFixed{UInt8,7})), Float32) @@ -189,8 +189,8 @@ for T in FixedPointNumbers.UF testapprox(T) end -@test !(UFixed8(0.5) < UFixed8(0.5)) -@test UFixed8(0.5) <= UFixed8(0.5) +@test !(N0f8(0.5) < N0f8(0.5)) +@test N0f8(0.5) <= N0f8(0.5) @test div(0x10uf8, 0x02uf8) == fld(0x10uf8, 0x02uf8) == 8 @test div(0x0fuf8, 0x02uf8) == fld(0x0fuf8, 0x02uf8) == 7 @@ -205,14 +205,14 @@ r = 1uf8:1uf8:48uf8 @test length(r) == 48 counter = 0 -for x in UFixed8(0):eps(UFixed8):UFixed8(1) +for x in N0f8(0):eps(N0f8):N0f8(1) counter += 1 end @test counter == 256 # Promotion within UFixed -@test @inferred(promote(UFixed8(0.2), UFixed8(0.8))) === - (UFixed8(0.2), UFixed8(0.8)) +@test @inferred(promote(N0f8(0.2), N0f8(0.8))) === + (N0f8(0.2), N0f8(0.8)) @test @inferred(promote(UFixed{UInt16,3}(0.2), UFixed{UInt8,3}(0.86))) === (UFixed{UInt16,3}(0.2), UFixed{UInt16,3}(0.86)) @test @inferred(promote(UFixed{UInt8,7}(0.197), UFixed{UInt8,4}(0.8))) === @@ -227,12 +227,12 @@ end @test UFixed{UInt16,4}(1) == UFixed{UInt8,6}(1) @test UFixed{UInt16,4}(0.2) == UFixed{UInt8,6}(0.2) -@test promote_type(UFixed8,Float32,Int) == Float32 -@test promote_type(UFixed8,Int,Float32) == Float32 -@test promote_type(Int,UFixed8,Float32) == Float32 -@test promote_type(Int,Float32,UFixed8) == Float32 -@test promote_type(Float32,Int,UFixed8) == Float32 -@test promote_type(Float32,UFixed8,Int) == Float32 +@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 = 0xaauf8 @@ -254,7 +254,7 @@ end a = rand(UInt8, 10) rfloat = similar(a, Float32) rfixed = similar(rfloat) -af8 = reinterpret(UFixed8, a) +af8 = reinterpret(N0f8, a) b = 0.5 bd, eld = scaledual(b, af8[1]) @@ -269,16 +269,16 @@ generic_scale!(rfixed, ad, b) @test rfloat == rfixed # reductions -a = UFixed8[0xffuf8, 0xffuf8] +a = N0f8[0xffuf8, 0xffuf8] @test sum(a) == 2.0 @test sum(a, 1) == [2.0] -a = UFixed14[3.2, 2.4] +a = N2f14[3.2, 2.4] acmp = Float64(a[1])*Float64(a[2]) @test prod(a) == acmp @test prod(a, 1) == [acmp] -x = UFixed8(0.3) +x = N0f8(0.3) for T in (Float16, Float32, Float64, BigFloat) y = convert(T, x) @test isa(y, T) From 65689dd6893e596ad61254e691004511a54d7e18 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 11 Oct 2016 11:07:09 -0500 Subject: [PATCH 3/6] Deprecate n*uf8 in favor of reinterpret(N0f8, n) --- src/deprecations.jl | 21 ++++++++++++++++- src/ufixed.jl | 10 --------- test/ufixed.jl | 55 +++++++++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/deprecations.jl b/src/deprecations.jl index 601d3ade..c52a8eea 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -8,7 +8,6 @@ import Base.@deprecate_binding @deprecate_binding UFixed16 N0f16 @deprecate_binding UfixedBase UFixed -@deprecate_binding UfixedConstructor UFixedConstructor @deprecate_binding Ufixed UFixed @deprecate_binding Ufixed8 N0f8 @deprecate_binding Ufixed10 N6f10 @@ -33,3 +32,23 @@ Compat.@dep_vectorize_1arg Real ufixed10 Compat.@dep_vectorize_1arg Real ufixed12 Compat.@dep_vectorize_1arg Real ufixed14 Compat.@dep_vectorize_1arg Real ufixed16 + +## The next lines mimic the floating-point literal syntax "3.2f0" +# construction using a UInt, i.e., 0xccuf8 +immutable UFixedConstructor{T,f} end +function *{T,f}(n::Integer, ::UFixedConstructor{T,f}) + i = 8*sizeof(T)-f + io = IOBuffer() + show(io, n) + nstr = takebuf_string(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(UFixed{T,f}, convert(T, n)) +end +const uf8 = UFixedConstructor{UInt8,8}() +const uf10 = UFixedConstructor{UInt16,10}() +const uf12 = UFixedConstructor{UInt16,12}() +const uf14 = UFixedConstructor{UInt16,14}() +const uf16 = UFixedConstructor{UInt16,16}() + +@deprecate_binding UfixedConstructor UFixedConstructor diff --git a/src/ufixed.jl b/src/ufixed.jl index 5656f0ed..b5de08a4 100644 --- a/src/ufixed.jl +++ b/src/ufixed.jl @@ -27,16 +27,6 @@ end reinterpret{T<:Unsigned, f}(::Type{UFixed{T,f}}, x::T) = UFixed{T,f}(x, 0) -## The next lines mimic the floating-point literal syntax "3.2f0" -# construction using a UInt, i.e., 0xccuf8 -immutable UFixedConstructor{T,f} end -*{T,f}(n::Integer, ::UFixedConstructor{T,f}) = UFixed{T,f}(n,0) -const uf8 = UFixedConstructor{UInt8,8}() -const uf10 = UFixedConstructor{UInt16,10}() -const uf12 = UFixedConstructor{UInt16,12}() -const uf14 = UFixedConstructor{UInt16,14}() -const uf16 = UFixedConstructor{UInt16,16}() - zero{T,f}(::Type{UFixed{T,f}}) = UFixed{T,f}(zero(T),0) function one{T<:UFixed}(::Type{T}) T(typemax(rawtype(T)) >> (8*sizeof(T)-nbitsfrac(T)), 0) diff --git a/test/ufixed.jl b/test/ufixed.jl index 16755f06..c85bf4c0 100644 --- a/test/ufixed.jl +++ b/test/ufixed.jl @@ -2,28 +2,29 @@ using FixedPointNumbers using Base.Test using Compat -@test reinterpret(0xa2uf8) == 0xa2 -@test reinterpret(0xa2uf10) == 0xa2 -@test reinterpret(0xa2uf12) == 0xa2 -@test reinterpret(0xa2uf14) == 0xa2 -@test reinterpret(0xa2uf16) == 0xa2 - -@test reinterpret(N0f8, 0xa2) == 0xa2uf8 -@test reinterpret(N6f10, 0x1fa2) == 0x1fa2uf10 -@test reinterpret(N4f12, 0x1fa2) == 0x1fa2uf12 -@test reinterpret(N2f14, 0x1fa2) == 0x1fa2uf14 -@test reinterpret(N0f16, 0x1fa2) == 0x1fa2uf16 +@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) == 0xffuf8 -@test N0f8(0.5) == 0x80uf8 -@test N2f14(1.0) == 0x3fffuf14 +@test N0f8(1.0) == reinterpret(N0f8, 0xff) +@test N0f8(0.5) == reinterpret(N0f8, 0x80) +@test N2f14(1.0) == reinterpret(N2f14, 0x3fff) v = @compat N4f12.([2]) -@test v == N4f12[0x1ffeuf12] +@test v == N4f12[reinterpret(N4f12, 0x1ffe)] @test isa(v, Vector{N4f12}) UF2 = (UFixed{UInt32,16}, UFixed{UInt64,3}, UFixed{UInt64,51}, UFixed{UInt128,7}, UFixed{UInt128,51}) @@ -114,7 +115,7 @@ end x = N0f8(0b01010001, 0) @test ~x == N0f8(0b10101110, 0) -@test -x == 0xafuf8 +@test -x == reinterpret(N0f8, 0xaf) @test isa(float(one(UFixed{UInt8,7})), Float32) @test isa(float(one(UFixed{UInt32,18})), Float64) @@ -192,16 +193,16 @@ end @test !(N0f8(0.5) < N0f8(0.5)) @test N0f8(0.5) <= N0f8(0.5) -@test div(0x10uf8, 0x02uf8) == fld(0x10uf8, 0x02uf8) == 8 -@test div(0x0fuf8, 0x02uf8) == fld(0x0fuf8, 0x02uf8) == 7 -@test Base.fld1(0x10uf8, 0x02uf8) == 8 -@test Base.fld1(0x0fuf8, 0x02uf8) == 8 -@test mod(0x10uf8, 0x02uf8) == rem(0x10uf8, 0x02uf8) == 0 -@test mod(0x0fuf8, 0x02uf8) == rem(0x0fuf8, 0x02uf8) == 0x01uf8 -@test mod1(0x10uf8, 0x02uf8) == 0x02uf8 -@test mod1(0x0fuf8, 0x02uf8) == 0x01uf8 +@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) -r = 1uf8:1uf8:48uf8 +r = reinterpret(N0f8, 0x01):reinterpret(N0f8, 0x01):reinterpret(N0f8, convert(UInt8, 48)) @test length(r) == 48 counter = 0 @@ -235,7 +236,7 @@ end @test promote_type(Float32,N0f8,Int) == Float32 # Show -x = 0xaauf8 +x = reinterpret(N0f8, 0xaa) iob = IOBuffer() show(iob, x) str = takebuf_string(iob) @@ -269,7 +270,7 @@ generic_scale!(rfixed, ad, b) @test rfloat == rfixed # reductions -a = N0f8[0xffuf8, 0xffuf8] +a = N0f8[reinterpret(N0f8, 0xff), reinterpret(N0f8, 0xff)] @test sum(a) == 2.0 @test sum(a, 1) == [2.0] From fdf550693357a55820be2c6f0fae6b5a43ff38b9 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 11 Oct 2016 13:31:17 -0500 Subject: [PATCH 4/6] Add a shell script to aid in fixing deprecations --- contrib/deprecation_UFixed.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 contrib/deprecation_UFixed.sh diff --git a/contrib/deprecation_UFixed.sh b/contrib/deprecation_UFixed.sh new file mode 100755 index 00000000..d67a604d --- /dev/null +++ b/contrib/deprecation_UFixed.sh @@ -0,0 +1,8 @@ +sed -i "s/UFixed8/N0f8/g" $* +sed -i "s/UFixed10/N6f10/g" $* +sed -i "s/UFixed12/N4f12/g" $* +sed -i "s/UFixed14/N2f14/g" $* +sed -i "s/UFixed16/N0f16/g" $* +# For types from ColorTypes +sed -i "s/U8/N0f8/g" $* +sed -i "s/U16/N0f16/g" $* From 9da3c8b9da3c2e4fffd7be19d1e27dcfe6b2117f Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 28 Jan 2017 14:52:23 +0900 Subject: [PATCH 5/6] Rename UFixed to Normed This rename reflects the nature of `UFixed` it is not just a unsigned fixpoint number type (for that you can use `Fixed{T<:Unsigned}`), but rather a number type that is normalised to a specific `one`. --- README.md | 18 ++-- src/FixedPointNumbers.jl | 4 +- src/deprecations.jl | 25 +++--- src/normed.jl | 161 ++++++++++++++++++++++++++++++++++ src/ufixed.jl | 161 ---------------------------------- test/{ufixed.jl => normed.jl} | 64 +++++++------- test/runtests.jl | 2 +- 7 files changed, 219 insertions(+), 216 deletions(-) create mode 100644 src/normed.jl delete mode 100644 src/ufixed.jl rename test/{ufixed.jl => normed.jl} (81%) diff --git a/README.md b/README.md index dd588451..1e7bd32a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ is the number of fraction bits. For `T<:Signed` (a signed integer), there is a fixed-point type `Fixed{T, f}`; for `T<:Unsigned` (an unsigned integer), there is the -`UFixed{T, f}` type. However, there are slight differences in behavior +`Normed{T, f}` type. However, there are slight differences in behavior that go beyond signed/unsigned distinctions. The `Fixed{T,f}` types use 1 bit for sign, and `f` bits to represent @@ -43,23 +43,23 @@ is interpreted as if the integer representation has been divided by because the range of `Int8` is from -128 to 127. -In contrast, the `UFixed{T,f}`, with `f` fraction bits, map the closed +In contrast, the `Normed{T,f}`, with `f` fraction bits, map the closed interval [0.0,1.0] to the span of numbers with `f` bits. For example, -the `UFixed8` type (aliased to `UFixed{UInt8,8}`) is represented +the `Normed8` type (aliased to `Normed{UInt8,8}`) is represented internally by a `UInt8`, and makes `0x00` equivalent to `0.0` and -`0xff` to `1.0`. Consequently, `UFixed` numbers are scaled by `2^f-1` -rather than `2^f`. The type aliases `UFixed10`, `UFixed12`, -`UFixed14`, and `UFixed16` are all based on `UInt16` and reach the +`0xff` to `1.0`. Consequently, `Normed` numbers are scaled by `2^f-1` +rather than `2^f`. The type aliases `Normed10`, `Normed12`, +`Normed14`, and `Normed16` are all based on `UInt16` and reach the value `1.0` at 10, 12, 14, and 16 bits, respectively (`0x03ff`, `0x0fff`, `0x3fff`, and `0xffff`). -To construct such a number, use `convert(UFixed12, 1.3)`, `UFixed12(1.3)`, `UFixed{UInt16,12}(1.3)`, or the literal syntax -`0x14ccuf12`. The latter syntax means to construct a `UFixed12` (it ends in +To construct such a number, use `convert(Normed12, 1.3)`, `Normed12(1.3)`, `Normed{UInt16,12}(1.3)`, or the literal syntax +`0x14ccuf12`. The latter syntax means to construct a `Normed12` (it ends in `uf12`) from the `UInt16` value `0x14cc`. More generally, an arbitrary number of bits from any of the standard unsigned integer widths can be used for the fractional part. For example: -`UFixed{UInt32,16}`, `UFixed{UInt64,3}`, `UFixed{UInt128,7}`. +`Normed{UInt32,16}`, `Normed{UInt64,3}`, `Normed{UInt128,7}`. There currently is no literal syntax for signed `Fixed` numbers. diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 7aea8927..8f526000 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -30,7 +30,7 @@ abstract FixedPoint{T <: Integer, f} <: Real export FixedPoint, Fixed, - UFixed, + Normed, # "special" typealiases # Q and U typealiases are exported in separate source files # literal constructor constants @@ -112,7 +112,7 @@ showcompact{T,f}(io::IO, x::FixedPoint{T,f}) = show(io, round(convert(Float64,x) include("fixed.jl") -include("ufixed.jl") +include("normed.jl") include("deprecations.jl") eps{T<:FixedPoint}(::Type{T}) = T(one(rawtype(T)),0) diff --git a/src/deprecations.jl b/src/deprecations.jl index c52a8eea..340bb9f8 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -7,8 +7,9 @@ import Base.@deprecate_binding @deprecate_binding UFixed14 N2f14 @deprecate_binding UFixed16 N0f16 -@deprecate_binding UfixedBase UFixed -@deprecate_binding Ufixed UFixed +@deprecate_binding UfixedBase Normed +@deprecate_binding Ufixed Normed +@deprecate_binding UFixed Normed @deprecate_binding Ufixed8 N0f8 @deprecate_binding Ufixed10 N6f10 @deprecate_binding Ufixed12 N4f12 @@ -35,20 +36,22 @@ Compat.@dep_vectorize_1arg Real ufixed16 ## The next lines mimic the floating-point literal syntax "3.2f0" # construction using a UInt, i.e., 0xccuf8 -immutable UFixedConstructor{T,f} end -function *{T,f}(n::Integer, ::UFixedConstructor{T,f}) +immutable NormedConstructor{T,f} end +function *{T,f}(n::Integer, ::NormedConstructor{T,f}) i = 8*sizeof(T)-f io = IOBuffer() show(io, n) nstr = takebuf_string(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(UFixed{T,f}, convert(T, n)) + reinterpret(Normed{T,f}, convert(T, n)) end -const uf8 = UFixedConstructor{UInt8,8}() -const uf10 = UFixedConstructor{UInt16,10}() -const uf12 = UFixedConstructor{UInt16,12}() -const uf14 = UFixedConstructor{UInt16,14}() -const uf16 = UFixedConstructor{UInt16,16}() +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 -@deprecate_binding UfixedConstructor UFixedConstructor diff --git a/src/normed.jl b/src/normed.jl new file mode 100644 index 00000000..52ea2519 --- /dev/null +++ b/src/normed.jl @@ -0,0 +1,161 @@ +# Normed{T,f} maps UInts from 0 to 2^f-1 to the range [0.0, 1.0] +# For example, Normed{UInt8,8} == N0f8 maps 0x00 to 0.0 and 0xff to 1.0 + +immutable Normed{T<:Unsigned,f} <: FixedPoint{T,f} + i::T + + Normed(i::Integer,_) = new(i%T) # for setting by raw representation + Normed(x) = convert(Normed{T,f}, x) +end + + rawtype{T,f}(::Type{Normed{T,f}}) = T + rawtype(x::Number) = rawtype(typeof(x)) +nbitsfrac{T,f}(::Type{Normed{T,f}}) = f +floattype{T<:Normed}(::Type{T}) = floattype(supertype(T)) +typechar{X<:Normed}(::Type{X}) = 'N' +signbits{X<:Normed}(::Type{X}) = 0 + +for T in (UInt8, UInt16, UInt32, UInt64) + for f in 0:sizeof(T)*8 + sym = Symbol(takebuf_string(showtype(_iotypealias, Normed{T,f}))) + @eval begin + typealias $sym Normed{$T,$f} + export $sym + end + end +end + +reinterpret{T<:Unsigned, f}(::Type{Normed{T,f}}, x::T) = Normed{T,f}(x, 0) + +zero{T,f}(::Type{Normed{T,f}}) = Normed{T,f}(zero(T),0) +function one{T<:Normed}(::Type{T}) + T(typemax(rawtype(T)) >> (8*sizeof(T)-nbitsfrac(T)), 0) +end +zero(x::Normed) = zero(typeof(x)) + one(x::Normed) = one(typeof(x)) +rawone(v) = reinterpret(one(v)) + +# Conversions +convert{T<:Normed}(::Type{T}, x::T) = x +convert{T1,T2,f}(::Type{Normed{T1,f}}, x::Normed{T2,f}) = Normed{T1,f}(convert(T1, x.i), 0) +function convert{T,T2,f}(::Type{Normed{T,f}}, x::Normed{T2}) + U = Normed{T,f} + y = round((rawone(U)/rawone(x))*reinterpret(x)) + (0 <= y) & (y <= typemax(T)) || throw_converterror(U, x) + reinterpret(U, _unsafe_trunc(T, y)) +end +convert(::Type{N0f16}, x::N0f8) = reinterpret(N0f16, convert(UInt16, 0x0101*reinterpret(x))) +convert{U<:Normed}(::Type{U}, x::Real) = _convert(U, rawtype(U), x) +function _convert{U<:Normed,T}(::Type{U}, ::Type{T}, x) + y = round(widen1(rawone(U))*x) + (0 <= y) & (y <= typemax(T)) || throw_converterror(U, x) + U(_unsafe_trunc(T, y), 0) +end +function _convert{U<:Normed}(::Type{U}, ::Type{UInt128}, x) + y = round(rawone(U)*x) # for UInt128, we can't widen + (0 <= y) & (y <= typemax(UInt128)) & (x <= Float64(typemax(U))) || throw_converterror(U, x) + U(_unsafe_trunc(UInt128, y), 0) +end + +rem{T<:Normed}(x::T, ::Type{T}) = x +rem{T<:Normed}(x::Normed, ::Type{T}) = reinterpret(T, _unsafe_trunc(rawtype(T), round((rawone(T)/rawone(x))*reinterpret(x)))) +rem{T<:Normed}(x::Real, ::Type{T}) = reinterpret(T, _unsafe_trunc(rawtype(T), round(rawone(T)*x))) + +# convert(::Type{AbstractFloat}, x::Normed) = convert(floattype(x), x) +float(x::Normed) = convert(floattype(x), x) + +convert(::Type{BigFloat}, x::Normed) = reinterpret(x)*(1/BigFloat(rawone(x))) +function convert{T<:AbstractFloat}(::Type{T}, x::Normed) + y = reinterpret(x)*(one(rawtype(x))/convert(T, rawone(x))) + convert(T, y) # needed for types like Float16 which promote arithmetic to Float32 +end +convert(::Type{Bool}, x::Normed) = x == zero(x) ? false : true +convert{T<:Integer}(::Type{T}, x::Normed) = convert(T, x*(1/one(T))) +convert{Ti<:Integer}(::Type{Rational{Ti}}, x::Normed) = convert(Ti, reinterpret(x))//convert(Ti, rawone(x)) +convert(::Type{Rational}, x::Normed) = reinterpret(x)//rawone(x) + +# Traits +abs(x::Normed) = x + +(-){T<:Normed}(x::T) = T(-reinterpret(x), 0) +(~){T<:Normed}(x::T) = T(~reinterpret(x), 0) + ++{T,f}(x::Normed{T,f}, y::Normed{T,f}) = Normed{T,f}(convert(T, x.i+y.i),0) +-{T,f}(x::Normed{T,f}, y::Normed{T,f}) = Normed{T,f}(convert(T, x.i-y.i),0) +*{T<:Normed}(x::T, y::T) = convert(T,convert(floattype(T), x)*convert(floattype(T), y)) +/{T<:Normed}(x::T, y::T) = convert(T,convert(floattype(T), x)/convert(floattype(T), y)) + +# Comparisons + <{T<:Normed}(x::T, y::T) = reinterpret(x) < reinterpret(y) +<={T<:Normed}(x::T, y::T) = reinterpret(x) <= reinterpret(y) + +# Functions +trunc{T<:Normed}(x::T) = T(div(reinterpret(x), rawone(T))*rawone(T),0) +floor{T<:Normed}(x::T) = trunc(x) +function round{T,f}(x::Normed{T,f}) + mask = convert(T, 1<<(f-1)) + y = trunc(x) + return convert(T, reinterpret(x)-reinterpret(y)) & mask>0 ? + Normed{T,f}(y+one(Normed{T,f})) : y +end +function ceil{T,f}(x::Normed{T,f}) + k = 8*sizeof(T)-f + mask = (typemax(T)<>k + y = trunc(x) + return convert(T, reinterpret(x)-reinterpret(y)) & (mask)>0 ? + Normed{T,f}(y+one(Normed{T,f})) : y +end + +trunc{T<:Integer}(::Type{T}, x::Normed) = convert(T, div(reinterpret(x), rawone(x))) +round{T<:Integer}(::Type{T}, x::Normed) = round(T, reinterpret(x)/rawone(x)) +floor{T<:Integer}(::Type{T}, x::Normed) = trunc(T, x) + ceil{T<:Integer}(::Type{T}, x::Normed) = ceil(T, reinterpret(x)/rawone(x)) + +isfinite(x::Normed) = true +isnan(x::Normed) = false +isinf(x::Normed) = false + +bswap{f}(x::Normed{UInt8,f}) = x +bswap(x::Normed) = typeof(x)(bswap(reinterpret(x)),0) + +function minmax{T<:Normed}(x::T, y::T) + a, b = minmax(reinterpret(x), reinterpret(y)) + T(a,0), T(b,0) +end + +# Iteration +# The main subtlety here is that iterating over 0x00uf8:0xffuf8 will wrap around +# unless we iterate using a wider type +@inline start{T<:Normed}(r::StepRange{T}) = widen1(reinterpret(r.start)) +@inline next{T<:Normed}(r::StepRange{T}, i::Integer) = (T(i,0), i+reinterpret(r.step)) +@inline function done{T<:Normed}(r::StepRange{T}, i::Integer) + i1, i2 = reinterpret(r.start), reinterpret(r.stop) + isempty(r) | (i < min(i1, i2)) | (i > max(i1, i2)) +end + +function decompose(x::Normed) + g = gcd(reinterpret(x), rawone(x)) + div(reinterpret(x),g), 0, div(rawone(x),g) +end + +# Promotions +promote_rule{T<:Normed,Tf<:AbstractFloat}(::Type{T}, ::Type{Tf}) = promote_type(floattype(T), Tf) +promote_rule{T<:Normed, R<:Rational}(::Type{T}, ::Type{R}) = R +function promote_rule{T<:Normed, Ti<:Union{Signed,Unsigned}}(::Type{T}, ::Type{Ti}) + floattype(T) +end +@generated function promote_rule{T1,T2,f1,f2}(::Type{Normed{T1,f1}}, ::Type{Normed{T2,f2}}) + f = max(f1, f2) # ensure we have enough precision + T = promote_type(T1, T2) + # make sure we have enough integer bits + i1, i2 = 8*sizeof(T1)-f1, 8*sizeof(T2)-f2 # number of integer bits for each + i = 8*sizeof(T)-f + while i < max(i1, i2) + T = widen1(T) + i = 8*sizeof(T)-f + end + :(Normed{$T,$f}) +end + +_unsafe_trunc{T}(::Type{T}, x::Integer) = x % T +_unsafe_trunc{T}(::Type{T}, x) = unsafe_trunc(T, x) diff --git a/src/ufixed.jl b/src/ufixed.jl deleted file mode 100644 index b5de08a4..00000000 --- a/src/ufixed.jl +++ /dev/null @@ -1,161 +0,0 @@ -# UFixed{T,f} maps UInts from 0 to 2^f-1 to the range [0.0, 1.0] -# For example, UFixed{UInt8,8} == N0f8 maps 0x00 to 0.0 and 0xff to 1.0 - -immutable UFixed{T<:Unsigned,f} <: FixedPoint{T,f} - i::T - - UFixed(i::Integer,_) = new(i%T) # for setting by raw representation - UFixed(x) = convert(UFixed{T,f}, x) -end - - rawtype{T,f}(::Type{UFixed{T,f}}) = T - rawtype(x::Number) = rawtype(typeof(x)) -nbitsfrac{T,f}(::Type{UFixed{T,f}}) = f -floattype{T<:UFixed}(::Type{T}) = floattype(supertype(T)) -typechar{X<:UFixed}(::Type{X}) = 'N' -signbits{X<:UFixed}(::Type{X}) = 0 - -for T in (UInt8, UInt16, UInt32, UInt64) - for f in 0:sizeof(T)*8 - sym = Symbol(takebuf_string(showtype(_iotypealias, UFixed{T,f}))) - @eval begin - typealias $sym UFixed{$T,$f} - export $sym - end - end -end - -reinterpret{T<:Unsigned, f}(::Type{UFixed{T,f}}, x::T) = UFixed{T,f}(x, 0) - -zero{T,f}(::Type{UFixed{T,f}}) = UFixed{T,f}(zero(T),0) -function one{T<:UFixed}(::Type{T}) - T(typemax(rawtype(T)) >> (8*sizeof(T)-nbitsfrac(T)), 0) -end -zero(x::UFixed) = zero(typeof(x)) - one(x::UFixed) = one(typeof(x)) -rawone(v) = reinterpret(one(v)) - -# Conversions -convert{T<:UFixed}(::Type{T}, x::T) = x -convert{T1,T2,f}(::Type{UFixed{T1,f}}, x::UFixed{T2,f}) = UFixed{T1,f}(convert(T1, x.i), 0) -function convert{T,T2,f}(::Type{UFixed{T,f}}, x::UFixed{T2}) - U = UFixed{T,f} - y = round((rawone(U)/rawone(x))*reinterpret(x)) - (0 <= y) & (y <= typemax(T)) || throw_converterror(U, x) - reinterpret(U, _unsafe_trunc(T, y)) -end -convert(::Type{N0f16}, x::N0f8) = reinterpret(N0f16, convert(UInt16, 0x0101*reinterpret(x))) -convert{U<:UFixed}(::Type{U}, x::Real) = _convert(U, rawtype(U), x) -function _convert{U<:UFixed,T}(::Type{U}, ::Type{T}, x) - y = round(widen1(rawone(U))*x) - (0 <= y) & (y <= typemax(T)) || throw_converterror(U, x) - U(_unsafe_trunc(T, y), 0) -end -function _convert{U<:UFixed}(::Type{U}, ::Type{UInt128}, x) - y = round(rawone(U)*x) # for UInt128, we can't widen - (0 <= y) & (y <= typemax(UInt128)) & (x <= Float64(typemax(U))) || throw_converterror(U, x) - U(_unsafe_trunc(UInt128, y), 0) -end - -rem{T<:UFixed}(x::T, ::Type{T}) = x -rem{T<:UFixed}(x::UFixed, ::Type{T}) = reinterpret(T, _unsafe_trunc(rawtype(T), round((rawone(T)/rawone(x))*reinterpret(x)))) -rem{T<:UFixed}(x::Real, ::Type{T}) = reinterpret(T, _unsafe_trunc(rawtype(T), round(rawone(T)*x))) - -# convert(::Type{AbstractFloat}, x::UFixed) = convert(floattype(x), x) -float(x::UFixed) = convert(floattype(x), x) - -convert(::Type{BigFloat}, x::UFixed) = reinterpret(x)*(1/BigFloat(rawone(x))) -function convert{T<:AbstractFloat}(::Type{T}, x::UFixed) - y = reinterpret(x)*(one(rawtype(x))/convert(T, rawone(x))) - convert(T, y) # needed for types like Float16 which promote arithmetic to Float32 -end -convert(::Type{Bool}, x::UFixed) = x == zero(x) ? false : true -convert{T<:Integer}(::Type{T}, x::UFixed) = convert(T, x*(1/one(T))) -convert{Ti<:Integer}(::Type{Rational{Ti}}, x::UFixed) = convert(Ti, reinterpret(x))//convert(Ti, rawone(x)) -convert(::Type{Rational}, x::UFixed) = reinterpret(x)//rawone(x) - -# Traits -abs(x::UFixed) = x - -(-){T<:UFixed}(x::T) = T(-reinterpret(x), 0) -(~){T<:UFixed}(x::T) = T(~reinterpret(x), 0) - -+{T,f}(x::UFixed{T,f}, y::UFixed{T,f}) = UFixed{T,f}(convert(T, x.i+y.i),0) --{T,f}(x::UFixed{T,f}, y::UFixed{T,f}) = UFixed{T,f}(convert(T, x.i-y.i),0) -*{T<:UFixed}(x::T, y::T) = convert(T,convert(floattype(T), x)*convert(floattype(T), y)) -/{T<:UFixed}(x::T, y::T) = convert(T,convert(floattype(T), x)/convert(floattype(T), y)) - -# Comparisons - <{T<:UFixed}(x::T, y::T) = reinterpret(x) < reinterpret(y) -<={T<:UFixed}(x::T, y::T) = reinterpret(x) <= reinterpret(y) - -# Functions -trunc{T<:UFixed}(x::T) = T(div(reinterpret(x), rawone(T))*rawone(T),0) -floor{T<:UFixed}(x::T) = trunc(x) -function round{T,f}(x::UFixed{T,f}) - mask = convert(T, 1<<(f-1)) - y = trunc(x) - return convert(T, reinterpret(x)-reinterpret(y)) & mask>0 ? - UFixed{T,f}(y+one(UFixed{T,f})) : y -end -function ceil{T,f}(x::UFixed{T,f}) - k = 8*sizeof(T)-f - mask = (typemax(T)<>k - y = trunc(x) - return convert(T, reinterpret(x)-reinterpret(y)) & (mask)>0 ? - UFixed{T,f}(y+one(UFixed{T,f})) : y -end - -trunc{T<:Integer}(::Type{T}, x::UFixed) = convert(T, div(reinterpret(x), rawone(x))) -round{T<:Integer}(::Type{T}, x::UFixed) = round(T, reinterpret(x)/rawone(x)) -floor{T<:Integer}(::Type{T}, x::UFixed) = trunc(T, x) - ceil{T<:Integer}(::Type{T}, x::UFixed) = ceil(T, reinterpret(x)/rawone(x)) - -isfinite(x::UFixed) = true -isnan(x::UFixed) = false -isinf(x::UFixed) = false - -bswap{f}(x::UFixed{UInt8,f}) = x -bswap(x::UFixed) = typeof(x)(bswap(reinterpret(x)),0) - -function minmax{T<:UFixed}(x::T, y::T) - a, b = minmax(reinterpret(x), reinterpret(y)) - T(a,0), T(b,0) -end - -# Iteration -# The main subtlety here is that iterating over 0x00uf8:0xffuf8 will wrap around -# unless we iterate using a wider type -@inline start{T<:UFixed}(r::StepRange{T}) = widen1(reinterpret(r.start)) -@inline next{T<:UFixed}(r::StepRange{T}, i::Integer) = (T(i,0), i+reinterpret(r.step)) -@inline function done{T<:UFixed}(r::StepRange{T}, i::Integer) - i1, i2 = reinterpret(r.start), reinterpret(r.stop) - isempty(r) | (i < min(i1, i2)) | (i > max(i1, i2)) -end - -function decompose(x::UFixed) - g = gcd(reinterpret(x), rawone(x)) - div(reinterpret(x),g), 0, div(rawone(x),g) -end - -# Promotions -promote_rule{T<:UFixed,Tf<:AbstractFloat}(::Type{T}, ::Type{Tf}) = promote_type(floattype(T), Tf) -promote_rule{T<:UFixed, R<:Rational}(::Type{T}, ::Type{R}) = R -function promote_rule{T<:UFixed, Ti<:Union{Signed,Unsigned}}(::Type{T}, ::Type{Ti}) - floattype(T) -end -@generated function promote_rule{T1,T2,f1,f2}(::Type{UFixed{T1,f1}}, ::Type{UFixed{T2,f2}}) - f = max(f1, f2) # ensure we have enough precision - T = promote_type(T1, T2) - # make sure we have enough integer bits - i1, i2 = 8*sizeof(T1)-f1, 8*sizeof(T2)-f2 # number of integer bits for each - i = 8*sizeof(T)-f - while i < max(i1, i2) - T = widen1(T) - i = 8*sizeof(T)-f - end - :(UFixed{$T,$f}) -end - -_unsafe_trunc{T}(::Type{T}, x::Integer) = x % T -_unsafe_trunc{T}(::Type{T}, x) = unsafe_trunc(T, x) diff --git a/test/ufixed.jl b/test/normed.jl similarity index 81% rename from test/ufixed.jl rename to test/normed.jl index c85bf4c0..97d4fa4c 100644 --- a/test/ufixed.jl +++ b/test/normed.jl @@ -27,7 +27,7 @@ v = @compat N4f12.([2]) @test v == N4f12[reinterpret(N4f12, 0x1ffe)] @test isa(v, Vector{N4f12}) -UF2 = (UFixed{UInt32,16}, UFixed{UInt64,3}, UFixed{UInt64,51}, UFixed{UInt128,7}, UFixed{UInt128,51}) +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 @@ -46,10 +46,10 @@ end @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(UFixed{UInt32,16}) == typemax(UInt32) // (2^16-1) -@test typemax(UFixed{UInt64,3}) == typemax(UInt64) // (2^3-1) -@test typemax(UFixed{UInt128,7}) == typemax(UInt128) // (2^7-1) -@test typemax(UFixed{UInt128,100}) == typemax(UInt128) // (UInt128(2)^100-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) @@ -60,8 +60,8 @@ end @test_throws ArgumentError N0f16(0xffff) @test_throws ArgumentError convert(N0f8, typemax(N6f10)) @test_throws ArgumentError convert(N0f16, typemax(N6f10)) -@test_throws ArgumentError convert(UFixed{UInt128,100}, 10^9) -@test_throws ArgumentError convert(UFixed{UInt128,100}, 10.0^9) +@test_throws ArgumentError convert(Normed{UInt128,100}, 10^9) +@test_throws ArgumentError convert(Normed{UInt128,100}, 10.0^9) x = N0f8(0.5) @test isfinite(x) == true @@ -73,9 +73,9 @@ x = N0f8(0.5) @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(UFixed{UInt32,16}, 1.1/typemax(UInt32)*2^16) == eps(UFixed{UInt32,16}) -@test convert(UFixed{UInt64,3}, 1.1/typemax(UInt64)*UInt64(2)^61) == eps(UFixed{UInt64,3}) -@test convert(UFixed{UInt128,7}, 1.1/typemax(UInt128)*UInt128(2)^121) == eps(UFixed{UInt128,7}) +@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) @@ -92,7 +92,7 @@ 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(UFixed{UInt16,7}, UFixed{UInt8,7}(0.504)) === UFixed{UInt16,7}(0.504) +@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) @@ -117,9 +117,9 @@ x = N0f8(0b01010001, 0) @test ~x == N0f8(0b10101110, 0) @test -x == reinterpret(N0f8, 0xaf) -@test isa(float(one(UFixed{UInt8,7})), Float32) -@test isa(float(one(UFixed{UInt32,18})), Float64) -@test isa(float(one(UFixed{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) for T in (FixedPointNumbers.UF..., UF2...) x = T(0x10,0) @@ -211,22 +211,22 @@ for x in N0f8(0):eps(N0f8):N0f8(1) end @test counter == 256 -# Promotion within UFixed +# Promotion within Normed @test @inferred(promote(N0f8(0.2), N0f8(0.8))) === (N0f8(0.2), N0f8(0.8)) -@test @inferred(promote(UFixed{UInt16,3}(0.2), UFixed{UInt8,3}(0.86))) === - (UFixed{UInt16,3}(0.2), UFixed{UInt16,3}(0.86)) -@test @inferred(promote(UFixed{UInt8,7}(0.197), UFixed{UInt8,4}(0.8))) === - (UFixed{UInt16,7}(0.197), UFixed{UInt16,7}(0.8)) - -@test UFixed{UInt16,16}(1) == UFixed{UInt8,8}(1) -@test UFixed{UInt16,16}(0.2) == UFixed{UInt8,8}(0.2) -@test UFixed{UInt16,8}(1) == UFixed{UInt8,8}(1) -@test UFixed{UInt16,8}(0.2) == UFixed{UInt8,8}(0.2) -@test UFixed{UInt16,16}(1) == UFixed{UInt8,6}(1) -@test UFixed{UInt16,16}(0.20635) == UFixed{UInt8,6}(0.20635) -@test UFixed{UInt16,4}(1) == UFixed{UInt8,6}(1) -@test UFixed{UInt16,4}(0.2) == UFixed{UInt8,6}(0.2) +@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 @@ -285,10 +285,10 @@ for T in (Float16, Float32, Float64, BigFloat) @test isa(y, T) end -for T in (UFixed{UInt8,8}, UFixed{UInt8,6}, - UFixed{UInt16,16}, UFixed{UInt16,14}, - UFixed{UInt32,32}, UFixed{UInt32,30}, - UFixed{UInt64,64}, UFixed{UInt64,62}) +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)) diff --git a/test/runtests.jl b/test/runtests.jl index 6880ce6e..ffb7872d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ if VERSION >= v"0.5.0" @test isempty(detect_ambiguities(FixedPointNumbers, Base, Core)) end -for f in ["ufixed.jl", "fixed.jl"] +for f in ["normed.jl", "fixed.jl"] println("Testing $f") include(f) end From af2a5c7d751ab7fdb34f2256d2605e1340d97470 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sat, 28 Jan 2017 04:44:31 -0600 Subject: [PATCH 6/6] Remove duplicate reinterpret definition --- src/fixed.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fixed.jl b/src/fixed.jl index 87ac160d..441c37d2 100644 --- a/src/fixed.jl +++ b/src/fixed.jl @@ -27,8 +27,6 @@ for T in (Int8, Int16, Int32, Int64) end end -reinterpret{T<:Signed, f}(::Type{Fixed{T,f}}, x::T) = Fixed{T,f}(x, 0) - # basic operators -{T,f}(x::Fixed{T,f}) = Fixed{T,f}(-x.i,0) abs{T,f}(x::Fixed{T,f}) = Fixed{T,f}(abs(x.i),0)