Skip to content

Commit

Permalink
simpler transitive Float == Rational equality implementation [#3102].
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed May 15, 2013
1 parent d2b964d commit db0cd95
Showing 1 changed file with 7 additions and 26 deletions.
33 changes: 7 additions & 26 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ typemin{T<:Integer}(::Type{Rational{T}}) = -one(T)//zero(T)
typemax{T<:Integer}(::Type{Rational{T}}) = one(T)//zero(T)

isinteger(x::Rational) = x.den == 1
isfloat64(x::Rational) = abs(x.num) <= x.den*maxintfloat(Float64)
isfloat64(x::Rational) = ispow2(x.den) & (abs(x.num) <= x.den*maxintfloat(Float64))

hash(x::Rational) = isinteger(x) ? hash(x.num) :
isfloat64(x) ? hash(float64(x)) :
bitmix(hash(x.num),hash(x.den))
bitmix(hash(x.num), hash(x.den))

-(x::Rational) = (-x.num) // x.den
+(x::Rational, y::Rational) = (x.num*y.den + x.den*y.num) // (x.den*y.den)
Expand All @@ -111,30 +111,11 @@ hash(x::Rational) = isinteger(x) ? hash(x.num) :
==(x::Integer , y::Rational) = y == x

# needed to avoid ambiguity between ==(x::Real, z::Complex) and ==(x::Rational, y::Number)
==(z::Complex , x::Rational) = isreal(z) && real(z) == x
==(x::Rational, z::Complex ) = isreal(z) && real(z) == x

function ==(x::Float64, y::Rational)
a, b = y.num, y.den
((x==0) & (a==0) | isinf(x) & (b==0) & (a==sign(x))) && return true
u = reinterpret(Uint64, x)
s = copysign(int(uint(!isdenormal(x))<<52 + u & 0x000fffffffffffff), x)
p = min(1074, 1075-int((u>>52) & 0x7ff))
za, zb, zs = trailing_zeros(a), trailing_zeros(b), trailing_zeros(s)
(za+p == zb+zs) & ((a>>>za) == (b>>>zb)*(s>>>zs)) # a*2^p == b*s
end
==(x::Rational, y::Float64) = y == x

function ==(x::Float32, y::Rational)
a, b = y.num, y.den
((x==0) & (a==0) | isinf(x) & (b==0) & (a==sign(x))) && return true
u = reinterpret(Uint32, x)
s = copysign(int(uint(!isdenormal(x))<<23 + u & 0x007fffff), x)
p = min(149, 150-int((u>>23) & 0xff))
za, zb, zs = trailing_zeros(a), trailing_zeros(b), trailing_zeros(s)
(za+p == zb+zs) & ((a>>>za) == (b>>>zb)*(s>>>zs)) # a*2^p == b*s
end
==(x::Rational, y::Float32) = y == x
==(z::Complex , x::Rational) = isreal(z) & (real(z) == x)
==(x::Rational, z::Complex ) = isreal(z) & (real(z) == x)

==(x::FloatingPoint, q::Rational) = ispow2(q.den) & (x == q.num/q.den) & (x*q.den == q.num)
==(q::Rational, x::FloatingPoint) = ispow2(q.den) & (x == q.num/q.den) & (x*q.den == q.num)

# TODO: fix inequalities to be in line with equality check
< (x::Rational, y::Rational) = x.den == y.den ? x.num < y.num : x.num*y.den < x.den*y.num
Expand Down

0 comments on commit db0cd95

Please sign in to comment.