cjdoris/Infinity.jl

`InfExtendedReal` can accidentally support a simultaneously positive/negative inf

omus opened this issue · 0 comments

omus commented

I've encountered an issue that only occurs on Linux 64-bit. Using Julia 1.4.2, Infinity 0.2.0, and Intervals 1.4.0 you can reproduce this issue:

julia> using Intervals, Infinity

julia> v = [
           [
               Interval{Closed, Open}(l, u),
               Interval{Open, Open}(l, u),
           ]
           for (l, u) in [(-∞, Inf)]
       ];

julia> v[1]
2-element Array{Interval{InfExtendedReal{Float64},L,Open} where L<:Bound,1}:
 Interval{InfExtendedReal{Float64},Closed,Open}(InfExtendedReal{Float64}(-∞), InfExtendedReal{Float64}(∞))
 Interval{InfExtendedReal{Float64},Open,Open}(InfExtendedReal{Float64}(∞), InfExtendedReal{Float64}(∞))

julia> x = first(b)
InfExtendedReal{Float64}(∞)

julia> Infinity.isposinf(x)
true

julia> Infinity.isneginf(x)
true

julia> x.flag
NEGINF::InfFlag = 0x02

julia> x.finitevalue
Inf

In attempting to reduce the problem further I came up with:

julia> function demo()
           l, u = InfExtendedReal{Float64}(-∞), InfExtendedReal{Float64}(Inf)
           a = Interval{InfExtendedReal{Float64}, Closed, Open}(l, u)
           b = Interval{InfExtendedReal{Float64}, Open, Open}(l, u)
           return first(b)
       end
demo (generic function with 1 method)

julia> y = demo()
InfExtendedReal{Float64}(∞)

julia> Infinity.isposinf(y)
true

julia> Infinity.isneginf(y)
true

julia> y.flag
NEGINF::InfFlag = 0x02

julia> y.finitevalue
Inf

There seems to be a couple of issues here but the main one is that an InfExtendedReal{Float64} can be simultaneously positive and negative infinity at the same time. The source of this problem appears to occur in the InfExtendedReal(::Infinite) constructor when we leave the finitevalue field undefined. If the undefined bits end up representing Inf where the sign differs from the flag field then this problem occurs.