DoubleFloats.jl icon indicating copy to clipboard operation
DoubleFloats.jl copied to clipboard

Inconsistent behaviour when comparing -0.0 with 0.0

Open andreasvarga opened this issue 2 years ago • 1 comments

The following behaviour I detected performing the function issymmetric on a symmetric matrix (thus preventing a correct test).

julia> C = Matrix(Hermitian(Complex{Double64}[1 0;0 1]))
2×2 Matrix{Complex{Double64}}:
 1.0 + 0.0im  0.0 + 0.0im
 0.0 - 0.0im  1.0 + 0.0im

julia> ishermitian(C)
true

julia> Ce = [real(C) imag(C); -imag(C) real(C)]  # construct a symmetric real matrix 
4×4 Matrix{Double64}:
  1.0   0.0   0.0  0.0
  0.0   1.0  -0.0  0.0
 -0.0  -0.0   1.0  0.0
  0.0  -0.0   0.0  1.0

julia> issymmetric(Ce)  # this test is in my opinion incorrect
false

julia> Ce == transpose(Ce)   # the matrix is symmetric as expected
true

The invalid test can be simply reproduced as shown bellow:


julia> y = -Double64(0)
-0.0

julia> z = Double64(0)
0.0

julia> y === z
false

julia> y == z
true

julia> y != z
true

andreasvarga avatar Mar 10 '23 11:03 andreasvarga

I wonder if replacing in compare.jl

@inline function (!=)(x::DoubleFloat{T}, y::DoubleFloat{T}) where {T<:IEEEFloat}
    return (LO(x) !== LO(y)) || (HI(x) !== HI(y) || posnegzeros(HI(x),HI(y)))
end

with

@inline function (!=)(x::DoubleFloat{T}, y::DoubleFloat{T}) where {T<:IEEEFloat}
    return (LO(x) !== LO(y)) || (HI(x) !== HI(y) && !posnegzeros(HI(x),HI(y)))
end

would fix the problem.

This corresponds to what is implemented in Base in operators.jl

!=(x, y) = !(x == y)

An equivalent fix would be

@inline function (!=)(x::DoubleFloat{T}, y::DoubleFloat{T}) where {T<:IEEEFloat}
    return !(==)(x,y)
end

andreasvarga avatar Mar 13 '23 12:03 andreasvarga