Skip to content

Commit

Permalink
Make π < π work as expected (#27797)
Browse files Browse the repository at this point in the history
Methods are added for < and <= comparing Irrationals. (The corresponding
> and >= are then handled by existing fallback methods.)

Currently, expressions like `ℯ < π` result in promotion to Float64.
This works most of the time. However, `π < π` does not result in
promotion and throws an error. This commit introduces a method
for comparing an Irrational to itself.

This commit also introduces a test to make sure that incorrect results
are not being returned due to different user-defined irrationals
rounding to the same Float64.
  • Loading branch information
perrutquist authored and JeffBezanson committed Jun 27, 2018
1 parent b610f42 commit 3a27c52
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
9 changes: 9 additions & 0 deletions base/irrationals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ float(::Type{<:AbstractIrrational}) = Float64
==(::Irrational{s}, ::Irrational{s}) where {s} = true
==(::AbstractIrrational, ::AbstractIrrational) = false

<(::Irrational{s}, ::Irrational{s}) where {s} = false
function <(x::AbstractIrrational, y::AbstractIrrational)
Float64(x) != Float64(y) || throw(MethodError(<, (x, y)))
return Float64(x) < Float64(y)
end

<=(::Irrational{s}, ::Irrational{s}) where {s} = true
<=(x::AbstractIrrational, y::AbstractIrrational) = x==y || x<y

# Irrationals, by definition, can't have a finite representation equal them exactly
==(x::AbstractIrrational, y::Real) = false
==(x::Real, y::AbstractIrrational) = false
Expand Down
13 changes: 13 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,19 @@ end
@test !(1 > NaN)
end

@testset "Irrationals compared with Irrationals" begin
for i in (π, ℯ, γ, catalan)
for j in (π, ℯ, γ, catalan)
@test isequal(i==j, Float64(i)==Float64(j))
@test isequal(i!=j, Float64(i)!=Float64(j))
@test isequal(i<=j, Float64(i)<=Float64(j))
@test isequal(i>=j, Float64(i)>=Float64(j))
@test isequal(i<j, Float64(i)<Float64(j))
@test isequal(i>j, Float64(i)>Float64(j))
end
end
end

@testset "Irrationals compared with Rationals and Floats" begin
@test Float64(pi,RoundDown) < pi
@test Float64(pi,RoundUp) > pi
Expand Down

0 comments on commit 3a27c52

Please sign in to comment.