Skip to content

Commit

Permalink
Merge pull request #108 from rdeits/fix-0.7
Browse files Browse the repository at this point in the history
Fix all v0.7 deprecations and errors, and convert tests to testsets
  • Loading branch information
Keno authored Jun 19, 2018
2 parents cf9ebc4 + a4ee304 commit 8bfa7c2
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 139 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- nightly
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())'
3 changes: 1 addition & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
julia 0.6
Compat 0.35
julia 0.7-alpha
8 changes: 4 additions & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -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\")"
9 changes: 2 additions & 7 deletions src/FixedPointNumbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -111,7 +105,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}
Expand All @@ -126,6 +120,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)
Expand Down
49 changes: 0 additions & 49 deletions src/deprecations.jl
Original file line number Diff line number Diff line change
@@ -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
38 changes: 18 additions & 20 deletions src/fixed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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::Char) 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),0)
Fixed{T,f}(x::AbstractFloat) where {T,f} = Fixed{T,f}(round(T, trunc(widen1(T),x)<<f + rem(x,1)*(one(widen1(T))<<f)),0)
Fixed{T,f}(x::Rational) where {T,f} = Fixed{T,f}(x.num)/Fixed{T,f}(x.den)

reinterpret(::Type{Fixed{T,f}}, x::T) where {T <: Signed,f} = Fixed{T,f}(x, 0)

typechar(::Type{X}) where {X <: Fixed} = 'Q'
Expand Down Expand Up @@ -43,33 +45,29 @@ abs(x::Fixed{T,f}) where {T,f} = Fixed{T,f}(abs(x.i),0)


# # conversions and promotions
convert(::Type{Fixed{T,f}}, x::Integer) where {T,f} = Fixed{T,f}(round(T, convert(widen1(T),x)<<f),0)
convert(::Type{Fixed{T,f}}, x::AbstractFloat) where {T,f} = Fixed{T,f}(round(T, trunc(widen1(T),x)<<f + rem(x,1)*(one(widen1(T))<<f)),0)
convert(::Type{Fixed{T,f}}, x::Rational) where {T,f} = Fixed{T,f}(x.num)/Fixed{T,f}(x.den)

rem(x::Integer, ::Type{Fixed{T,f}}) where {T,f} = Fixed{T,f}(rem(x,T)<<f,0)
rem(x::Real, ::Type{Fixed{T,f}}) where {T,f} = Fixed{T,f}(rem(Integer(trunc(x)),T)<<f + rem(Integer(round(rem(x,1)*(one(widen1(T))<<f))),T),0)

# convert{T,f}(::Type{AbstractFloat}, x::Fixed{T,f}) = convert(floattype(x), x)
float(x::Fixed) = convert(floattype(x), x)

convert(::Type{BigFloat}, x::Fixed{T,f}) where {T,f} =
convert(BigFloat,x.i>>f) + convert(BigFloat,x.i&(one(widen1(T))<<f - 1))/convert(BigFloat,one(widen1(T))<<f)
convert(::Type{TF}, x::Fixed{T,f}) where {TF <: AbstractFloat,T,f} =
convert(TF,x.i>>f) + convert(TF,x.i&(one(widen1(T))<<f - 1))/convert(TF,one(widen1(T))<<f)
Base.BigFloat(x::Fixed{T,f}) where {T,f} =
BigFloat(x.i>>f) + BigFloat(x.i&(one(widen1(T))<<f - 1))/BigFloat(one(widen1(T))<<f)
(::Type{TF})(x::Fixed{T,f}) where {TF <: AbstractFloat,T,f} =
TF(x.i>>f) + TF(x.i&(one(widen1(T))<<f - 1))/TF(one(widen1(T))<<f)

convert(::Type{Bool}, x::Fixed{T,f}) where {T,f} = x.i!=0
function convert(::Type{Integer}, x::Fixed{T,f}) where {T,f}
Base.Bool(x::Fixed{T,f}) where {T,f} = x.i!=0
function Base.Integer(x::Fixed{T,f}) where {T,f}
isinteger(x) || throw(InexactError())
convert(Integer, x.i>>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-1))//(one(widen1(T))<<f))
(::Type{TR})(x::Fixed{T,f}) where {TR <: Rational,T,f} =
TR(x.i>>f + (x.i&(1<<f-1))//(one(widen1(T))<<f))

promote_rule(ft::Type{Fixed{T,f}}, ::Type{TI}) where {T,f,TI <: Integer} = Fixed{T,f}
promote_rule(::Type{Fixed{T,f}}, ::Type{TF}) where {T,f,TF <: AbstractFloat} = TF
Expand Down
34 changes: 16 additions & 18 deletions src/normed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ struct Normed{T<:Unsigned,f} <: FixedPoint{T,f}
i::T

Normed{T, f}(i::Integer,_) where {T,f} = new{T, f}(i%T) # for setting by raw representation
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::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

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))
Normed{T1,f}(x::Normed{T2,f}) where {T1 <: Unsigned,T2 <: Unsigned,f} = Normed{T1,f}(convert(T1, x.i), 0)

typechar(::Type{X}) where {X <: Normed} = 'N'
signbits(::Type{X}) where {X <: Normed} = 0

Expand All @@ -38,17 +38,16 @@ one(x::Normed) = oneunit(x)
rawone(v) = reinterpret(one(v))

# Conversions
convert(::Type{U}, x::U) where {U <: Normed} = x
convert(::Type{Normed{T1,f}}, x::Normed{T2,f}) where {T1 <: Unsigned,T2 <: Unsigned,f} = Normed{T1,f}(convert(T1, x.i), 0)
function convert(::Type{Normed{T,f}}, x::Normed{T2}) where {T <: Unsigned,T2 <: Unsigned,f}
function Normed{T,f}(x::Normed{T2}) where {T <: Unsigned,T2 <: Unsigned,f}
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{U}, x::Real) where {U <: Normed} = _convert(U, rawtype(U), x)
N0f16(x::N0f8) = reinterpret(N0f16, convert(UInt16, 0x0101*reinterpret(x)))

(::Type{U})(x::Real) where {U <: Normed} = _convert(U, rawtype(U), x)

convert(::Type{N0f16}, x::N0f8) = reinterpret(N0f16, convert(UInt16, 0x0101*reinterpret(x)))
function _convert(::Type{U}, ::Type{T}, x) where {U <: Normed,T}
y = round(widen1(rawone(U))*x)
(0 <= y) & (y <= typemax(T)) || throw_converterror(U, x)
Expand All @@ -70,19 +69,18 @@ rem(x::Normed, ::Type{T}) where {T <: Normed} = reinterpret(T, _unsafe_trunc(raw
rem(x::Real, ::Type{T}) where {T <: Normed} = reinterpret(T, _unsafe_trunc(rawtype(T), round(rawone(T)*x)))
rem(x::Float16, ::Type{T}) where {T <: Normed} = rem(Float32(x), T) # avoid overflow

# 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(::Type{T}, x::Normed) where {T <: AbstractFloat}
Base.BigFloat(x::Normed) = reinterpret(x)*(1/BigFloat(rawone(x)))
function (::Type{T})(x::Normed) where {T <: AbstractFloat}
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(::Type{Integer}, x::Normed) = convert(Integer, x*1.0)
convert(::Type{T}, x::Normed) where {T <: Integer} = convert(T, x*(1/oneunit(T)))
convert(::Type{Rational{Ti}}, x::Normed) where {Ti <: Integer} = convert(Ti, reinterpret(x))//convert(Ti, rawone(x))
convert(::Type{Rational}, x::Normed) = reinterpret(x)//rawone(x)
Base.Bool(x::Normed) = x == zero(x) ? false : true
Base.Integer(x::Normed) = convert(Integer, x*1.0)
(::Type{T})(x::Normed) where {T <: Integer} = convert(T, x*(1/oneunit(T)))
Base.Rational{Ti}(x::Normed) where {Ti <: Integer} = convert(Ti, reinterpret(x))//convert(Ti, rawone(x))
Base.Rational(x::Normed) = reinterpret(x)//rawone(x)

# Traits
abs(x::Normed) = x
Expand Down
43 changes: 31 additions & 12 deletions test/fixed.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -49,20 +49,25 @@ function test_fixed(::Type{T}, f) where {T}
end
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)
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
end

@testset "modulus" begin
T = Fixed{Int8,7}
for i = -1.0:0.1:typemax(T)
@test i % T === T(i)
Expand All @@ -76,66 +81,79 @@ for i = -64.0:0.1:typemax(T)
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}]
local T
testapprox(T) # defined in ufixed.jl
end
end

# reductions
@testset "reductions" begin
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]
@test sum(a, dims=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]
@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)
local T
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

# Floating-point conversions
@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

# Show
@testset "Show" begin
x = Fixed{Int32,5}(0.25)
iob = IOBuffer()
show(iob, x)
str = String(take!(iob))
@test str == "0.25Q26f5"
@test eval(parse(str)) == x
@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})
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)
end
end

@testset "realmin" begin
# issue #79
@test realmin(Q11f4) == Q11f4(0.06)
end

# Test disambiguation constructors
@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),
Expand All @@ -144,7 +162,8 @@ for (T, f) in ((Int8, 7),
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)
for x in range(-1, stop=BigFloat(tmax)-tol, length=50)
@test abs(Fixed{T, f}(x) - x) <= tol
end
end
end
Loading

0 comments on commit 8bfa7c2

Please sign in to comment.