diff --git a/base/complex.jl b/base/complex.jl index 07e48a005db15..b4606517a30b5 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -118,10 +118,8 @@ convert(::Type{Complex}, x::Real) = complex(x) ==(x::Real, z::Complex) = isreal(z) && real(z) == x isequal(z::Complex, w::Complex) = isequal(real(z),real(w)) & isequal(imag(z),imag(w)) -isequal(z::Complex, x::Real) = isreal(z) && isequal(real(z),x) -isequal(x::Real, z::Complex) = isreal(z) && isequal(real(z),x) -hash(z::Complex) = (r = hash(real(z)); isreal(z) ? r : bitmix(r,hash(imag(z)))) +hash(z::Complex) = bitmix(hash(real(z)),hash(imag(z))) conj(z::Complex) = complex(real(z),-imag(z)) abs(z::Complex) = hypot(real(z), imag(z)) diff --git a/base/dict.jl b/base/dict.jl index 31bf5585426e5..4ea7926818642 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -218,28 +218,13 @@ function hash(x::Integer) return h end -@eval function hash(x::FloatingPoint) - if trunc(x) == x - # hash as integer if equal to some integer. note the result of - # float to int conversion is only defined for in-range values. - if x < 0 - if $(float64(typemin(Int64))) <= x - return hash(int64(x)) - end - else - # note: float64(typemax(Uint64)) == 2^64 - if x < $(float64(typemax(Uint64))) - return hash(uint64(x)) - end - end - end - isnan(x) ? $(hash64(NaN)) : hash64(float64(x)) -end +hash(x::Float32) = hash(reinterpret(Uint32, isnan(x) ? NaN32 : x)) +hash(x::Float64) = hash(reinterpret(Uint64, isnan(x) ? NaN : x)) function hash(t::Tuple) h = int(0) for i=1:length(t) - h = bitmix(h,int(hash(t[i]))) + h = bitmix(h,int(hash(t[i]))+42) end return uint(h) end @@ -252,6 +237,9 @@ function hash(a::Array) return uint(h) end +# make sure Array{Bool} and BitArray can be equivalent +hash(a::Array{Bool}) = hash(bitpack(a)) + hash(x::ANY) = object_id(x) if WORD_SIZE == 64 @@ -268,6 +256,8 @@ else s.data, length(s.data), uint32(seed)) end +hash(s::String) = hash(bytestring(s)) + # dict diff --git a/base/float.jl b/base/float.jl index eaeefebf5a77a..f93fee64796fd 100644 --- a/base/float.jl +++ b/base/float.jl @@ -157,7 +157,7 @@ mod{T<:FloatingPoint}(x::T, y::T) = rem(y+rem(x,y),y) <=(x::Float32, y::Float32) = le_float(unbox(Float32,x),unbox(Float32,y)) <=(x::Float64, y::Float64) = le_float(unbox(Float64,x),unbox(Float64,y)) -isequal(x::FloatingPoint, y::FloatingPoint) = +isequal{T<:FloatingPoint}(x::T, y::T) = ((x==y) & (signbit(x)==signbit(y))) | (isnan(x)&isnan(y)) isequal(x::Float32, y::Float32) = fpiseq(unbox(Float32,x),unbox(Float32,y)) @@ -165,8 +165,6 @@ isequal(x::Float64, y::Float64) = fpiseq(unbox(Float64,x),unbox(Float64,y)) isless (x::Float32, y::Float32) = fpislt(unbox(Float32,x),unbox(Float32,y)) isless (x::Float64, y::Float64) = fpislt(unbox(Float64,x),unbox(Float64,y)) -isequal(a::Integer, b::FloatingPoint) = (a==b) & isequal(float(a),b) -isequal(a::FloatingPoint, b::Integer) = isequal(b, a) isless (a::Integer, b::FloatingPoint) = (a (x,y) = y.=(x,y) = y.<=x -# these definitions allow Number types to implement -# == and < instead of isequal and isless, which is more idiomatic: -isequal(x::Number, y::Number) = x==y +# this definition allows Number types to implement < instead of isless, +# which is more idiomatic: isless(x::Real, y::Real) = x