Skip to content

Commit

Permalink
Merge pull request #3110 from JuliaLang/sk/float-rational-cmp
Browse files Browse the repository at this point in the history
transitive comparison of floats and rationals
  • Loading branch information
StefanKarpinski committed May 15, 2013
2 parents c7e7360 + bdc2034 commit 635997a
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
14 changes: 7 additions & 7 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,13 +111,13 @@ 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
==(z::Complex , x::Rational) = isreal(z) & (real(z) == x)
==(x::Rational, z::Complex ) = isreal(z) & (real(z) == x)

==(x::Rational, y::Number ) = x.num == x.den*y
==(x::Number , y::Rational) = y == x
==(x::Rational, y::FloatingPoint) = x.den==0 ? oftype(y,x)==y : x.num == x.den*y
==(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
< (x::Rational, y::Real ) = x.num < x.den*y
< (x::Real , y::Rational) = x*y.den < y.num
Expand Down
15 changes: 14 additions & 1 deletion test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ end

for a = -5:5, b = -5:5
if a == b == 0; continue; end
@test a//b == a/b
@test !ispow2(b) || a//b == a/b
@test a//b == a//b
@test a//b == convert(Rational,a/b)
if b == 0
Expand All @@ -708,6 +708,19 @@ for a = -5:5, b = -5:5
end
end

@test 0.5 == 1//2
@test 0.1 != 1//10
@test 0.1 == 3602879701896397//36028797018963968
@test realmin() != 1//(BigInt(2)^1022+1)
@test realmin() == 1//(BigInt(2)^1022)
@test realmin() != 1//(BigInt(2)^1022-1)
@test realmin()/2 != 1//(BigInt(2)^1023+1)
@test realmin()/2 == 1//(BigInt(2)^1023)
@test realmin()/2 != 1//(BigInt(2)^1023-1)
@test nextfloat(0.0) != 1//(BigInt(2)^1074+1)
@test nextfloat(0.0) == 1//(BigInt(2)^1074)
@test nextfloat(0.0) != 1//(BigInt(2)^1074-1)

@test sqrt(2) == 1.4142135623730951

@test 1+1.5 == 2.5
Expand Down

0 comments on commit 635997a

Please sign in to comment.