From 9da3c8b9da3c2e4fffd7be19d1e27dcfe6b2117f Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 28 Jan 2017 14:52:23 +0900 Subject: [PATCH] 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