DoubleFloats.jl
DoubleFloats.jl copied to clipboard
Inconsistent behaviour when comparing -0.0 with 0.0
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
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