From 2cf1c151161ca92142a820fb5ff63dd3ba160b57 Mon Sep 17 00:00:00 2001 From: kimikage Date: Tue, 24 Dec 2019 02:57:18 +0900 Subject: [PATCH] Fix `isinteger` and Commonize predicates (e.g. `isnan`) --- src/FixedPointNumbers.jl | 5 ++++- src/normed.jl | 4 ---- test/fixed.jl | 33 ++++++++++++++++++++++++++++++++- test/normed.jl | 29 ++++++++++++++++++++++++++--- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index f59013a5..ffb9962f 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -62,7 +62,10 @@ function isapprox(x::FixedPoint, y::FixedPoint; rtol=0, atol=max(eps(x), eps(y)) end # predicates -isinteger(x::FixedPoint{T,f}) where {T,f} = (x.i&(1< (rawone(x) >> 0x1) ? d + oneunit(rawtype(x)) : d) end -isfinite(x::Normed) = true -isnan(x::Normed) = false -isinf(x::Normed) = false - # Iteration # The main subtlety here is that iterating over N0f8(0):N0f8(1) will wrap around # unless we iterate using a wider type diff --git a/test/fixed.jl b/test/fixed.jl index e0038088..63fb60cb 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -17,7 +17,6 @@ function test_fixed(::Type{T}, f) where {T} if !(typemin(T) < x <= typemax(T)) continue end - # isinteger(x) && @show x fx = convert(T,x) @test convert(T,convert(Float64, fx)) == fx @test convert(T,convert(Float64, -fx)) == -fx @@ -243,6 +242,38 @@ end @test isa(float(one(Fixed{Int32,25})), Float64) end +@testset "predicates" begin + @test isfinite(1Q7f8) + @test !isnan(1Q7f8) + @test !isinf(1Q7f8) + + @testset "isinteger" begin + for T in (Int8, Int16) + @testset "isinteger(::Fixed{$T,$f})" for f = 0:bitwidth(T)-1 + F = Fixed{T,f} + xs = typemin(F):eps(F):typemax(F) + @test all(x -> isinteger(x) == isinteger(float(x)), xs) + end + end + for T in (Int32, Int64) + @testset "isinteger(::Fixed{$T,$f})" for f = 0:bitwidth(T)-1 + F = Fixed{T,f} + fzero, fmax, fmin = zero(F), typemax(F), typemin(F) + if f == 0 + @test isinteger(fzero) & isinteger(fmax) & isinteger(fmin) + else + @test isinteger(fzero) & !isinteger(fmax) & isinteger(fmin) + end + end + end + @testset "isinteger(::Fixed{Int8,8})" begin # TODO: remove this testset + @test !isinteger(Fixed{Int8,8}(-0.5)) + @test isinteger(Fixed{Int8,8}(0.0)) + @test !isinteger(Fixed{Int8,8}(127/256)) + end + end +end + @testset "Show" begin x = Fixed{Int32,5}(0.25) iob = IOBuffer() diff --git a/test/normed.jl b/test/normed.jl index 80c5949c..0151ba14 100644 --- a/test/normed.jl +++ b/test/normed.jl @@ -80,9 +80,6 @@ end @testset "conversion" begin x = N0f8(0.5) @test convert(N0f8, x) === x - @test isfinite(x) == true - @test isnan(x) == false - @test isinf(x) == false @test convert(N0f8, 1.1/typemax(UInt8)) == eps(N0f8) @test convert(N6f10, 1.1/typemax(UInt16)*64) == eps(N6f10) @@ -334,6 +331,32 @@ end @test_throws OverflowError length(NInt1(0):NInt1(1):typemax(NInt1)) end +@testset "predicates" begin + @test isfinite(1N8f8) + @test !isnan(1N8f8) + @test !isinf(1N8f8) + + @testset "isinteger" begin + for T in (UInt8, UInt16) + @testset "isinteger(::Normed{$T,$f})" for f = 1:bitwidth(T) + N = Normed{T,f} + xs = typemin(N):eps(N):typemax(N) + @test all(x -> isinteger(x) == isinteger(float(x)), xs) + end + end + for T in (UInt32, UInt64) + @testset "isinteger(::Normed{$T,$f})" for f = 1:bitwidth(T) + N = Normed{T,f} + if f == 1 + @test isinteger(zero(N)) & isinteger(oneunit(N)) + else + @test !isinteger(oneunit(N) - eps(N)) & isinteger(oneunit(N)) + end + end + end + end +end + @testset "Promotion within Normed" begin @test @inferred(promote(N0f8(0.2), N0f8(0.8))) === (N0f8(0.2), N0f8(0.8))