Skip to content

Commit

Permalink
Fix RoundNearestTiesAway (#29700)
Browse files Browse the repository at this point in the history
Fixes #29698.
  • Loading branch information
simonbyrne authored Nov 19, 2018
1 parent 1952bec commit 1c5cde2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
5 changes: 2 additions & 3 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,8 @@ function round(x::AbstractFloat, ::RoundingMode{:NearestTiesAway})
ifelse(x==y,y,trunc(2*x-y))
end
# Java-style round
function round(x::AbstractFloat, ::RoundingMode{:NearestTiesUp})
y = floor(x)
ifelse(x==y,y,copysign(floor(2*x-y),x))
function round(x::T, ::RoundingMode{:NearestTiesUp}) where {T <: AbstractFloat}
copysign(floor((x + (T(0.25) - eps(T(0.5)))) + (T(0.25) + eps(T(0.5)))), x)
end

# isapprox: approximate equality of numbers
Expand Down
41 changes: 41 additions & 0 deletions test/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,47 @@ end
@test_throws DivideError round(Int64,badness,RoundNearestTiesUp)
end

@testset "rounding properties" for Tf in [Float16,Float32,Float64]
# these should hold for all u, but we just test the smallest and largest
# of each binade

for i in exponent(floatmin(Tf)):exponent(floatmax(Tf))
for u in [ldexp(Tf(1.0), i), -ldexp(Tf(1.0), i),
ldexp(prevfloat(Tf(2.0)), i), -ldexp(prevfloat(Tf(2.0)), i)]

r = round(u, RoundNearest)
if isfinite(u)
@test isfinite(r)
@test isinteger(r)
@test abs(r-u) < 0.5 || abs(r-u) == 0.5 && isinteger(r/2)
@test signbit(u) == signbit(r)
else
@test u === r
end

r = round(u, RoundNearestTiesAway)
if isfinite(u)
@test isfinite(r)
@test isinteger(r)
@test abs(r-u) < 0.5 || (r-u) == copysign(0.5,u)
@test signbit(u) == signbit(r)
else
@test u === r
end

r = round(u, RoundNearestTiesUp)
if isfinite(u)
@test isfinite(r)
@test isinteger(r)
@test -0.5 < r-u <= 0.5
@test signbit(u) == signbit(r)
else
@test u === r
end
end
end
end

@testset "rounding difficult values" begin
for x = 2^53-10:2^53+10
y = Float64(x)
Expand Down

0 comments on commit 1c5cde2

Please sign in to comment.