Skip to content

Commit

Permalink
extend iseven/isodd to Number (JuliaLang#38976)
Browse files Browse the repository at this point in the history
* extend iseven/isodd to Number

* add PR num to NEWS
  • Loading branch information
stevengj committed Dec 25, 2020
1 parent 60b68ce commit 570384e
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 9 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Standard library changes
------------------------

* `islowercase` and `isuppercase` are now compliant with the Unicode lower/uppercase categories ([#38574]).
* `iseven` and `isodd` functions now support non-`Integer` numeric types ([#38976]).

#### Package Manager

Expand Down
2 changes: 2 additions & 0 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,8 @@ function issubnormal(x::T) where {T<:IEEEFloat}
end

ispow2(x::AbstractFloat) = !iszero(x) && frexp(x)[1] == 0.5
iseven(x::AbstractFloat) = isinteger(x) && (abs(x) > maxintfloat(x) || iseven(Integer(x)))
isodd(x::AbstractFloat) = isinteger(x) && abs(x) maxintfloat(x) && isodd(Integer(x))

@eval begin
typemin(::Type{Float16}) = $(bitcast(Float16, 0xfc00))
Expand Down
14 changes: 8 additions & 6 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ inv(x::Integer) = float(one(x)) / float(x)
(/)(x::BitInteger, y::BitInteger) = float(x) / float(y)

"""
isodd(x::Integer) -> Bool
isodd(x::Number) -> Bool
Return `true` if `x` is odd (that is, not divisible by 2), and `false` otherwise.
Return `true` if `x` is an odd integer (that is, an integer not divisible by 2), and `false` otherwise.
# Examples
```jldoctest
Expand All @@ -106,12 +106,13 @@ julia> isodd(10)
false
```
"""
isodd(n::Integer) = rem(n, 2) != 0
isodd(n::Number) = isreal(n) && isodd(real(n))
isodd(n::Real) = isinteger(n) && !iszero(rem(Integer(n), 2))

"""
iseven(x::Integer) -> Bool
iseven(x::Number) -> Bool
Return `true` if `x` is even (that is, divisible by 2), and `false` otherwise.
Return `true` if `x` is an even integer (that is, an integer divisible by 2), and `false` otherwise.
# Examples
```jldoctest
Expand All @@ -122,7 +123,8 @@ julia> iseven(10)
true
```
"""
iseven(n::Integer) = !isodd(n)
iseven(n::Number) = isreal(n) && iseven(real(n))
iseven(n::Real) = isinteger(n) && iszero(rem(Integer(n), 2))

signbit(x::Integer) = x < 0
signbit(x::Unsigned) = false
Expand Down
5 changes: 4 additions & 1 deletion test/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1205,9 +1205,12 @@ end
# complex with non-concrete eltype
@test_throws ErrorException complex(Union{Complex{Int}, Nothing}[])

@testset "ispow2" begin
@testset "ispow2 and iseven/isodd" begin
@test ispow2(4+0im)
@test ispow2(0.25+0im)
@test !ispow2(4+5im)
@test !ispow2(7+0im)
@test iseven(6+0im) && !isodd(6+0im)
@test !iseven(7+0im) && isodd(7+0im)
@test !iseven(6+1im) && !isodd(7+1im)
end
11 changes: 10 additions & 1 deletion test/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,23 @@ end
end
end

@testset "ispow2" begin
@testset "ispow2 and iseven/isodd" begin
for T in (Float16,Float32,Float64,BigFloat)
for x in (0.25, 1.0, 4.0, exp2(T(exponent(floatmax(T)))), exp2(T(exponent(floatmin(T)))))
@test ispow2(T(x))
end
for x in (1.5, 0.0, 7.0, NaN, Inf)
@test !ispow2(T(x))
end
for x in (0, 134)
@test iseven(T(x)) && iseven(T(-x))
@test isodd(T(x+1)) && isodd(T(-x-1))
end
let x = maxintfloat(T) * π
@test iseven(x) && iseven(-x)
@test !isodd(x) && !isodd(-x)
end
@test !iseven(0.5) && !isodd(0.5)
end
end

Expand Down
5 changes: 4 additions & 1 deletion test/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -595,11 +595,14 @@ end
@test -2//3 * 0x1 == 0x1 * -2//3 == -2//3
end

@testset "ispow2" begin
@testset "ispow2 and iseven/isodd" begin
@test ispow2(4//1)
@test ispow2(1//8)
@test !ispow2(3//8)
@test !ispow2(0//1)
@test iseven(4//1) && !isodd(4//1)
@test !iseven(3//1) && isodd(3//1)
@test !iseven(3//8) && !isodd(3//8)
end

@testset "checked_den with different integer types" begin
Expand Down

0 comments on commit 570384e

Please sign in to comment.