diff --git a/src/HalfIntegers.jl b/src/HalfIntegers.jl index c47a8f0..ce50b29 100644 --- a/src/HalfIntegers.jl +++ b/src/HalfIntegers.jl @@ -23,6 +23,7 @@ export # Functions half, ishalfinteger, + ishalfodd, onehalf, twice @@ -561,6 +562,37 @@ ishalfinteger(::HalfIntegerOrInteger) = true ishalfinteger(::AbstractIrrational) = false ishalfinteger(::Missing) = missing +""" + ishalfodd(x) + +Test whether `x` is numerically equal to some half-odd-integer. + +# Examples + +```jldoctest +julia> ishalfodd(3.5) +true + +julia> ishalfodd(2) +false + +julia> ishalfodd(1//3) +false +``` +""" +ishalfodd(x::Number) = _isodd(twice(x)) +ishalfodd(x::Rational) = denominator(x) == 2 +ishalfodd(::Integer) = false +ishalfodd(::Missing) = missing + +if VERSION ≥ v"1.7" + _isodd(x) = isodd(x) +else + _isodd(x::Real) = isodd(x) + _isodd(n::Number) = isreal(n) && _isodd(real(n)) + _isodd(x::AbstractFloat) = isinteger(x) && abs(x) ≤ maxintfloat(x) && _isodd(Integer(x)) +end + @static if VERSION ≥ v"1.7.0-DEV.263" Base.range_start_stop_length(start::T, stop::T, len::Integer) where T<:HalfInteger = Base._linspace(float(T), start, stop, len) diff --git a/test/customtypes.jl b/test/customtypes.jl index a2617df..27fa117 100644 --- a/test/customtypes.jl +++ b/test/customtypes.jl @@ -62,6 +62,7 @@ Base.convert(::Type{One}, x::Int) = x == 1 ? One() : error("can't convert $x to @testset "Properties" begin @test isfinite(MyHalfInt(2)) @test ishalfinteger(MyHalfInt(3/2)) + @test ishalfodd(MyHalfInt(3/2)) @test isinteger(MyHalfInt(3)) @test !isinteger(MyHalfInt(3/2)) @test iszero(MyHalfInt(0)) diff --git a/test/runtests.jl b/test/runtests.jl index 9138633..9280a98 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -374,6 +374,24 @@ end @test !ishalfinteger(im) end + @testset "ishalfodd" begin + for T in (halfinttypes..., halfuinttypes..., :BigHalfInt) + @eval @test !ishalfodd($T(3)) + @eval @test ishalfodd($T(5/2)) + end + @test !ishalfodd(5) + @test !ishalfodd(big(-5)) + @test ishalfodd(5//2) + @test ishalfodd(-3//2) + @test !ishalfodd(4//3) + @test !ishalfodd(2.0) + @test ishalfodd(-7.5) + @test !ishalfodd(2.3) + @test !ishalfodd(π) + @test !ishalfodd(ℯ) + @test !ishalfodd(im) + end + @testset "isinteger" begin for T in (halfinttypes..., :BigHalfInt) @eval @test isinteger($T(3)) @@ -1690,6 +1708,7 @@ end @test onehalf(missing) === onehalf(Missing) === missing @test ishalfinteger(missing) === missing + @test ishalfodd(missing) === missing end include("ranges.jl")