From 3aeb892c3305e2dd214046983d57eff8e9edb31f Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Fri, 18 May 2018 16:57:51 -0700 Subject: [PATCH 1/4] Deprecate setrounding Fixes #26935. This is the "minimal" change of deprecating Float32/Float64 support. --- base/deprecated.jl | 5 ++++ base/rounding.jl | 20 ------------- test/rounding.jl | 71 ++++++---------------------------------------- 3 files changed, 13 insertions(+), 83 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 49decc44e4c3e..aeda17c4508c9 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1669,6 +1669,11 @@ end @deprecate next(s::AbstractString, i::Integer) iterate(s, i) @deprecate done(s::AbstractString, i::Integer) i > ncodeunits(s) +function Rounding.setrounding(::Type{T}, r::RoundingMode) where {T<:Union{Float32,Float64}} + depwarn("""`setrounding` for `Float32` and `Float64` has been deprecated, and will not be available in future versions.""", :setrounding) + Rounding.setrounding_raw(T, Rounding.to_fenv(r)) +end + # END 0.7 deprecations # BEGIN 1.0 deprecations diff --git a/base/rounding.jl b/base/rounding.jl index 534f7ad043a9b..28c9a6552741b 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -109,25 +109,6 @@ function from_fenv(r::Integer) end end -""" - setrounding(T, mode) - -Set the rounding mode of floating point type `T`, controlling the rounding of basic -arithmetic functions ([`+`](@ref), [`-`](@ref), [`*`](@ref), -[`/`](@ref) and [`sqrt`](@ref)) and type conversion. Other numerical -functions may give incorrect or invalid values when using rounding modes other than the -default `RoundNearest`. - -Note that this may affect other types, for instance changing the rounding mode of -[`Float64`](@ref) will change the rounding mode of [`Float32`](@ref). -See [`RoundingMode`](@ref) for available modes. - -!!! warning - - This feature is still experimental, and may give unexpected or incorrect values. -""" -setrounding(T::Type, mode) - """ rounding(T) @@ -142,7 +123,6 @@ See [`RoundingMode`](@ref) for available modes. setrounding_raw(::Type{<:Union{Float32,Float64}}, i::Integer) = ccall(:fesetround, Int32, (Int32,), i) rounding_raw(::Type{<:Union{Float32,Float64}}) = ccall(:fegetround, Int32, ()) -setrounding(::Type{T}, r::RoundingMode) where {T<:Union{Float32,Float64}} = setrounding_raw(T,to_fenv(r)) rounding(::Type{T}) where {T<:Union{Float32,Float64}} = from_fenv(rounding_raw(T)) """ diff --git a/test/rounding.jl b/test/rounding.jl index 148742c9ad09f..a5cebccea5941 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -19,36 +19,6 @@ using Test @test a - b === -c @test b - a === c end - @testset "RoundToZero" begin - setrounding(Float64,RoundToZero) do - @test a + b === d - @test - a - b === -d - @test a - b === -c - @test b - a === c - end - # Sanity check to see if we have returned to RoundNearest - @test a + b === 1. - @test - a - b === -1. - @test a - b == -c - @test b - a == c - end - - @testset "RoundUp" begin - setrounding(Float64,RoundUp) do - @test a + b === 1. - @test - a - b === -d - @test a - b === -c - @test b - a === c - end - end - @testset "RoundDown" begin - setrounding(Float64,RoundDown) do - @test a + b === d - @test - a - b === -1. - @test a - b === -c - @test b - a === c - end - end end @testset "Float32 checks" begin @@ -63,49 +33,24 @@ end @test a32 - b32 === -c32 @test b32 - a32 === c32 end - @testset "RoundToZero" begin - setrounding(Float32,RoundToZero) do - @test a32 + b32 === d32 - @test - a32 - b32 === -d32 - @test a32 - b32 === -c32 - @test b32 - a32 === c32 - end - - # Sanity check to see if we have returned to RoundNearest - @test a32 + b32 === 1.0f0 - @test - a32 - b32 === -1.0f0 - @test a32 - b32 == -c32 - @test b32 - a32 == c32 - end - @testset "RoundUp" begin - setrounding(Float32,RoundUp) do - @test a32 + b32 === 1.0f0 - @test - a32 - b32 === -d32 - @test a32 - b32 === -c32 - @test b32 - a32 === c32 - end - end - @testset "RoundDown" begin - setrounding(Float32,RoundDown) do - @test a32 + b32 === d32 - @test - a32 - b32 === -1.0f0 - @test a32 - b32 === -c32 - @test b32 - a32 === c32 - end - end end @testset "convert with rounding" begin for v = [sqrt(2),-1/3,nextfloat(1.0),prevfloat(1.0),nextfloat(-1.0), prevfloat(-1.0),nextfloat(0.0),prevfloat(0.0)] + pn = Float32(v,RoundNearest) @test pn == convert(Float32,v) + pz = Float32(v,RoundToZero) - @test pz == setrounding(()->convert(Float32,v), Float64, RoundToZero) + @test abs(pz) <= abs(v) < nextfloat(abs(pz)) + @test signbit(pz) == signbit(v) + pd = Float32(v,RoundDown) - @test pd == setrounding(()->convert(Float32,v), Float64, RoundDown) + @test pd <= v < nextfloat(pd) + pu = Float32(v,RoundUp) - @test pu == setrounding(()->convert(Float32,v), Float64, RoundUp) + @test prevfloat(pu) < v <= pu @test pn == pd || pn == pu @test v > 0 ? pz == pd : pz == pu From 58123f05d21cd33c39a647acdcfed2fb53058e3b Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Wed, 23 May 2018 15:49:18 -0700 Subject: [PATCH 2/4] remove doc references --- base/rounding.jl | 22 ------------------- .../integers-and-floating-point-numbers.md | 18 --------------- 2 files changed, 40 deletions(-) diff --git a/base/rounding.jl b/base/rounding.jl index 28c9a6552741b..973d60e41ff88 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -137,28 +137,6 @@ equivalent to: setrounding(T, old) See [`RoundingMode`](@ref) for available rounding modes. - -!!! warning - - This feature is still experimental, and may give unexpected or incorrect values. A - known problem is the interaction with compiler optimisations, e.g. - - julia> setrounding(Float64,RoundDown) do - 1.1 + 0.1 - end - 1.2000000000000002 - - Here the compiler is *constant folding*, that is evaluating a known constant - expression at compile time, however the rounding mode is only changed at runtime, so - this is not reflected in the function result. This can be avoided by moving constants - outside the expression, e.g. - - julia> x = 1.1; y = 0.1; - - julia> setrounding(Float64,RoundDown) do - x + y - end - 1.2 """ function setrounding(f::Function, ::Type{T}, rounding::RoundingMode) where T old_rounding_raw = rounding_raw(T) diff --git a/doc/src/manual/integers-and-floating-point-numbers.md b/doc/src/manual/integers-and-floating-point-numbers.md index 80b00927ca0eb..231df41143583 100644 --- a/doc/src/manual/integers-and-floating-point-numbers.md +++ b/doc/src/manual/integers-and-floating-point-numbers.md @@ -496,27 +496,9 @@ appropriate representable value. However, the manner in which this rounding is d changed if required according to the rounding modes presented in the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008). -```jldoctest -julia> x = 1.1; y = 0.1; - -julia> x + y -1.2000000000000002 - -julia> setrounding(Float64,RoundDown) do - x + y - end -1.2 -``` - The default mode used is always [`RoundNearest`](@ref), which rounds to the nearest representable value, with ties rounded towards the nearest value with an even least significant bit. -!!! warning - Rounding is generally only correct for basic arithmetic functions ([`+`](@ref), [`-`](@ref), - [`*`](@ref), [`/`](@ref) and [`sqrt`](@ref)) and type conversion operations. Many other - functions assume the default [`RoundNearest`](@ref) mode is set, and can give erroneous results - when operating under other rounding modes. - ### Background and References Floating-point arithmetic entails many subtleties which can be surprising to users who are unfamiliar From 3cb9cb0650534afc4b7d2d032a5cd9c8216ed3ca Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Wed, 23 May 2018 15:53:55 -0700 Subject: [PATCH 3/4] add NEWS item --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index f739507be8f47..a4a0d057fd968 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1196,6 +1196,8 @@ Deprecated or removed * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935]). + Command-line option changes --------------------------- @@ -1508,3 +1510,4 @@ Command-line option changes [#26670]: https://github.com/JuliaLang/julia/issues/26670 [#26775]: https://github.com/JuliaLang/julia/issues/26775 [#26932]: https://github.com/JuliaLang/julia/issues/26932 +[#26935]: https://github.com/JuliaLang/julia/issues/26935 From 09c48e2e130955ce7492919e1ae783eb8bbe0a85 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Thu, 24 May 2018 15:39:21 -0700 Subject: [PATCH 4/4] add docs back in --- base/rounding.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/base/rounding.jl b/base/rounding.jl index 973d60e41ff88..6e35c4d09b94c 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -109,6 +109,19 @@ function from_fenv(r::Integer) end end +""" + setrounding(T, mode) + +Set the rounding mode of floating point type `T`, controlling the rounding of basic +arithmetic functions ([`+`](@ref), [`-`](@ref), [`*`](@ref), +[`/`](@ref) and [`sqrt`](@ref)) and type conversion. Other numerical +functions may give incorrect or invalid values when using rounding modes other than the +default `RoundNearest`. + +Note that this is currently only supported for `T == BigFloat`. +""" +setrounding(T::Type, mode) + """ rounding(T)