Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use distinct types for RealInfinity #37

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/Infinities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,17 @@ function mod(x::Real, ::Infinity)
x
end

abstract type RealInfinity <: Real end
struct PositiveInfinity <: RealInfinity end
struct NegativeInfinity <: RealInfinity end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, this also makes those two types into singleton types, which may allow for better code in a few places (avoiding allocations)


signbit(::PositiveInfinity) = false
signbit(::NegativeInfinity) = true

struct RealInfinity <: Real
signbit::Bool
end

RealInfinity() = RealInfinity(false)
RealInfinity(::Infinity) = RealInfinity()
RealInfinity() = PositiveInfinity()
RealInfinity(::Infinity) = PositiveInfinity()
RealInfinity(x::RealInfinity) = x
RealInfinity(x::Bool) = ifelse(x, NegativeInfinity(), PositiveInfinity())

-(::Infinity) = RealInfinity(true)
-(x::Number, ::Infinity) = x + (-∞)
Expand All @@ -127,7 +129,7 @@ RealInfinity(x::RealInfinity) = x
isinf(::RealInfinity) = true
isfinite(::RealInfinity) = false

promote_rule(::Type{Infinity}, ::Type{RealInfinity}) = RealInfinity
promote_rule(::Type{Infinity}, ::Type{<:RealInfinity}) = RealInfinity
_convert(::Type{RealInfinity}, ::Infinity) = RealInfinity(false)

_convert(::Type{Float16}, x::RealInfinity) = sign(x)*Inf16
Expand All @@ -136,8 +138,6 @@ _convert(::Type{Float64}, x::RealInfinity) = sign(x)*Inf64
_convert(::Type{T}, x::RealInfinity) where {T<:Real} = sign(x)*convert(T, Inf)
(::Type{T})(x::RealInfinity) where {T<:Real} = _convert(T, x)


signbit(y::RealInfinity) = y.signbit
sign(y::RealInfinity) = 1-2signbit(y)
angle(x::RealInfinity) = π*signbit(x)
mod(::RealInfinity, ::RealInfinity) = NotANumber()
Expand All @@ -150,9 +150,9 @@ end
string(y::RealInfinity) = signbit(y) ? "-∞" : "+∞"
show(io::IO, y::RealInfinity) = print(io, string(y))

==(x::RealInfinity, y::Infinity) = !x.signbit
==(y::Infinity, x::RealInfinity) = !x.signbit
==(x::RealInfinity, y::RealInfinity) = x.signbit == y.signbit
==(x::RealInfinity, y::Infinity) = !signbit(x)
==(y::Infinity, x::RealInfinity) = !signbit(x)
==(x::RealInfinity, y::RealInfinity) = signbit(x) == signbit(y)

==(x::RealInfinity, y::Number) = isinf(y) && signbit(y) == signbit(x)
==(y::Number, x::RealInfinity) = x == y
Expand Down Expand Up @@ -196,7 +196,7 @@ function -(x::RealInfinity, y::RealInfinity)
x
end

-(y::RealInfinity) = RealInfinity(!y.signbit)
-(y::RealInfinity) = RealInfinity(!signbit(y))

function +(x::RealInfinity, y::RealInfinity)
x == y || throw(ArgumentError("Angles must be the same to add ∞"))
Expand Down Expand Up @@ -231,12 +231,12 @@ for OP in (:<,:≤)
end


min(x::RealInfinity, y::RealInfinity) = RealInfinity(x.signbit | y.signbit)
max(x::RealInfinity, y::RealInfinity) = RealInfinity(x.signbit & y.signbit)
min(x::Real, y::RealInfinity) = y.signbit ? y : x
max(x::Real, y::RealInfinity) = y.signbit ? x : y
min(x::RealInfinity, y::Real) = x.signbit ? x : y
max(x::RealInfinity, y::Real) = x.signbit ? y : x
min(x::RealInfinity, y::RealInfinity) = RealInfinity(signbit(x) | signbit(y))
max(x::RealInfinity, y::RealInfinity) = RealInfinity(signbit(x) & signbit(y))
min(x::Real, y::RealInfinity) = signbit(y) ? y : x
max(x::Real, y::RealInfinity) = signbit(y) ? x : y
min(x::RealInfinity, y::Real) = signbit(x) ? x : y
max(x::RealInfinity, y::Real) = signbit(x) ? y : x
min(x::RealInfinity, ::Infinity) = x
max(::RealInfinity, ::Infinity) = ∞
min(::Infinity, x::RealInfinity) = x
Expand Down Expand Up @@ -275,7 +275,7 @@ isfinite(::ComplexInfinity) = false


promote_rule(::Type{Infinity}, ::Type{ComplexInfinity{T}}) where T = ComplexInfinity{T}
promote_rule(::Type{RealInfinity}, ::Type{ComplexInfinity{T}}) where T = ComplexInfinity{T}
promote_rule(::Type{<:RealInfinity}, ::Type{ComplexInfinity{T}}) where T = ComplexInfinity{T}
convert(::Type{ComplexInfinity{T}}, ::Infinity) where T = ComplexInfinity{T}()
convert(::Type{ComplexInfinity}, ::Infinity) = ComplexInfinity()
convert(::Type{ComplexInfinity{T}}, x::RealInfinity) where T = ComplexInfinity{T}(x)
Expand Down