Skip to content

Commit

Permalink
Fix #10124 by adding check for undefined behaviour
Browse files Browse the repository at this point in the history
(cherry picked from commit aa739ec)
ref #14520
  • Loading branch information
simonbyrne authored and tkelman committed Jan 9, 2016
1 parent 3d0a0e0 commit 275231a
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,25 @@ function cmp(x::AbstractFloat, y::Real)
ifelse(x<y, -1, ifelse(x>y, 1, 0))
end

# Exact Float (Tf) vs Integer (Ti) comparisons
# Assumes:
# - typemax(Ti) == 2^n-1
# - typemax(Ti) can't be exactly represented by Tf:
# => Tf(typemax(Ti)) == 2^n or Inf
# - typemin(Ti) can be exactly represented by Tf
#
# 1. convert y::Ti to float fy::Tf
# 2. perform Tf comparison x vs fy
# 3. if x == fy, check if (1) resulted in rounding:
# a. convert fy back to Ti and compare with original y
# b. unsafe_convert undefined behaviour if fy == Tf(typemax(Ti))
# (but consequently x == fy > y)
for Ti in (Int64,UInt64,Int128,UInt128)
for Tf in (Float32,Float64)
@eval begin
function ==(x::$Tf, y::$Ti)
fy = ($Tf)(y)
(x == fy) & (y == unsafe_trunc($Ti,fy))
(x == fy) & (fy != $(Tf(typemax(Ti)))) & (y == unsafe_trunc($Ti,fy))
end
==(y::$Ti, x::$Tf) = x==y

Expand Down

0 comments on commit 275231a

Please sign in to comment.