From e77e7eb22fdcadb56a3428b61f2a85380fb369d7 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Sun, 1 Dec 2013 21:48:03 +0000 Subject: [PATCH] add BitsFloat abstract type, leverage dispatch for rounding modes --- NEWS.md | 6 +++- base/deprecated.jl | 8 +++++ base/exports.jl | 3 -- base/mpfr.jl | 21 +++--------- base/rounding.jl | 12 +++---- .../integers-and-floating-point-numbers.rst | 6 ++-- doc/stdlib/base.rst | 34 +++++++------------ test/mpfr.jl | 6 ++-- test/rounding.jl | 12 +++---- 9 files changed, 48 insertions(+), 60 deletions(-) diff --git a/NEWS.md b/NEWS.md index 28c6541249148..87d5515f551fb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -49,6 +49,10 @@ Deprecated or removed * The `Stat` type is renamed `StatStruct` ([#4670]) + * `set_rounding`, `get_rounding` and `with_rounding` now take an additional + argument specifying the floating point type to which they apply. The old + behaviour and `[get/set/with]_bigfloat_rounding` functions are deprecated ([#5007]) + [#4775]: https://github.com/JuliaLang/julia/issues/4775 [#4870]: https://github.com/JuliaLang/julia/issues/4870 [#4766]: https://github.com/JuliaLang/julia/issues/4766 @@ -56,7 +60,7 @@ Deprecated or removed [#4759]: https://github.com/JuliaLang/julia/issues/4759 [#4819]: https://github.com/JuliaLang/julia/issues/4819 [#4670]: https://github.com/JuliaLang/julia/issues/4670 - +[#5007]: https://github.com/JuliaLang/julia/issues/5007 Julia v0.2.0 Release Notes diff --git a/base/deprecated.jl b/base/deprecated.jl index 63554120901b8..89311493d1ed1 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -359,5 +359,13 @@ const Stat = StatStruct export CharString const CharString = UTF32String +@deprecate set_rounding(r::RoundingMode) set_rounding(Float64,r) +@deprecate get_rounding() get_rounding(Float64) +@deprecate with_rounding(f::Function, r::RoundingMode) with_rounding(f::Function, Float64, r) + +@deprecate set_bigfloat_rounding(r::RoundingMode) set_rounding(BigFloat,r) +@deprecate get_bigfloat_rounding() get_rounding(BigFloat) +@deprecate with_bigfloat_rounding(f::Function, r::RoundingMode) with_rounding(f::Function, BigFloat, r) + # 0.3 discontinued functions diff --git a/base/exports.jl b/base/exports.jl index 5edfa1b3bbe07..ad2478ba0b431 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -842,9 +842,6 @@ export get_bigfloat_precision, set_bigfloat_precision, with_bigfloat_precision, - get_bigfloat_rounding, - set_bigfloat_rounding, - with_bigfloat_rounding, get_rounding, set_rounding, with_rounding, diff --git a/base/mpfr.jl b/base/mpfr.jl index d7e4c2717a6f5..62121162034ff 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -4,10 +4,7 @@ export BigFloat, get_bigfloat_precision, set_bigfloat_precision, - with_bigfloat_precision, - set_bigfloat_rounding, - get_bigfloat_rounding, - with_bigfloat_rounding + with_bigfloat_precision import Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, bessely, @@ -20,7 +17,7 @@ import itrunc, eps, signbit, sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2, serialize, deserialize, inf, nan, hash, cbrt, typemax, typemin, - realmin, realmax + realmin, realmax, get_rounding, set_rounding import Base.Math.lgamma_r @@ -615,8 +612,8 @@ function from_mpfr(c::Integer) RoundingMode(c) end -get_bigfloat_rounding() = from_mpfr(ROUNDING_MODE[end]) -set_bigfloat_rounding(r::RoundingMode) = ROUNDING_MODE[end] = to_mpfr(r) +get_rounding(::Type{BigFloat}) = from_mpfr(ROUNDING_MODE[end]) +set_rounding(::Type{BigFloat},r::RoundingMode) = ROUNDING_MODE[end] = to_mpfr(r) function copysign(x::BigFloat, y::BigFloat) z = BigFloat() @@ -701,16 +698,6 @@ function with_bigfloat_precision(f::Function, precision::Integer) end end -function with_bigfloat_rounding(f::Function, rounding::RoundingMode) - old_rounding = get_bigfloat_rounding() - set_bigfloat_rounding(rounding) - try - return f() - finally - set_bigfloat_rounding(old_rounding) - end -end - function string(x::BigFloat) lng = 128 for i = 1:2 diff --git a/base/rounding.jl b/base/rounding.jl index 497323ad5fab2..2b3aa5756f7c7 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -46,16 +46,16 @@ function from_fenv(r::Integer) end end -set_rounding(r::RoundingMode) = ccall(:fesetround, Cint, (Cint,), to_fenv(r)) -get_rounding() = from_fenv(ccall(:fegetround, Cint, ())) +set_rounding{T<:Union(Float32,Float64)}(::Type{T},r::RoundingMode) = ccall(:fesetround, Cint, (Cint,), to_fenv(r)) +get_rounding{T<:Union(Float32,Float64)}(::Type{T}) = from_fenv(ccall(:fegetround, Cint, ())) -function with_rounding(f::Function, rounding::RoundingMode) - old_rounding = get_rounding() - set_rounding(rounding) +function with_rounding{T}(f::Function, ::Type{T}, rounding::RoundingMode) + old_rounding = get_rounding(T) + set_rounding(T,rounding) try return f() finally - set_rounding(old_rounding) + set_rounding(T,old_rounding) end end diff --git a/doc/manual/integers-and-floating-point-numbers.rst b/doc/manual/integers-and-floating-point-numbers.rst index 0e32d4e5b5e98..4d5446e7483dd 100644 --- a/doc/manual/integers-and-floating-point-numbers.rst +++ b/doc/manual/integers-and-floating-point-numbers.rst @@ -500,7 +500,7 @@ presented in the `IEEE 754 standard julia> 1.1 + 0.1 1.2000000000000002 - julia> with_rounding(RoundDown) do + julia> with_rounding(Float64,RoundDown) do 1.1 + 0.1 end 1.2 @@ -603,12 +603,12 @@ will take these changes in account: .. doctest:: - julia> with_bigfloat_rounding(RoundUp) do + julia> with_rounding(BigFloat,RoundUp) do BigFloat(1) + BigFloat("0.1") end 1.100000000000000000000000000000000000000000000000000000000000000000000000000003e+00 with 256 bits of precision - julia> with_bigfloat_rounding(RoundDown) do + julia> with_rounding(BigFloat,RoundDown) do BigFloat(1) + BigFloat("0.1") end 1.099999999999999999999999999999999999999999999999999999999999999999999999999986e+00 with 256 bits of precision diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index ad278f588dd18..80b9850a750ba 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -3135,22 +3135,26 @@ Numbers ``BigFloat(2.1)`` may not yield what you expect. You may prefer to initialize constants using strings, e.g., ``BigFloat("2.1")``. -.. function:: get_rounding() +.. function:: get_rounding(T) - Get the current floating point rounding mode. Valid modes are ``RoundNearest``, ``RoundToZero``, ``RoundUp`` and ``RoundDown``. + Get the current floating point rounding mode for type ``T``. Valid modes + are ``RoundNearest``, ``RoundToZero``, ``RoundUp``, ``RoundDown``, and + ``RoundFromZero`` (``BigFloat`` only). -.. function:: set_rounding(mode) +.. function:: set_rounding(T, mode) - Set the floating point rounding mode. See ``get_rounding`` for available modes + Set the rounding mode of floating point type ``T``. Note that this may + affect other types, for instance changing the rounding mode of ``Float64`` + will change the rounding mode of ``Float32``. See ``get_rounding`` for available modes -.. function:: with_rounding(f::Function,mode) +.. function:: with_rounding(f::Function, T, mode) - Change the floating point rounding mode for the duration of ``f``. It is logically equivalent to:: + Change the rounding mode of floating point type ``T`` for the duration of ``f``. It is logically equivalent to:: - old = get_rounding() - set_rounding(mode) + old = get_rounding(T) + set_rounding(T, mode) f() - set_rounding(old) + set_rounding(T, old) See ``get_rounding`` for available rounding modes. @@ -3240,18 +3244,6 @@ The `BigFloat` type implements arbitrary-precision floating-point aritmetic usin f() set_bigfloat_precision(old) -.. function:: get_bigfloat_rounding() - - Get the current BigFloat rounding mode. Valid modes are ``RoundNearest``, ``RoundToZero``, ``RoundUp``, ``RoundDown``, ``RoundFromZero`` - -.. function:: set_bigfloat_rounding(mode) - - Set the BigFloat rounding mode. See get_bigfloat_rounding for available modes - -.. function:: with_bigfloat_rounding(f::Function,mode) - - Change the BigFloat rounding mode for the duration of ``f``. See ``get_bigfloat_rounding`` for available rounding modes; see also ``with_bigfloat_precision``. - Random Numbers -------------- diff --git a/test/mpfr.jl b/test/mpfr.jl index 83424e0093d42..ffab08ae26b3c 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -82,14 +82,14 @@ z = BigFloat(30) # rounding modes with_bigfloat_precision(4) do # default mode is round to nearest - down, up = with_bigfloat_rounding(RoundNearest) do + down, up = with_rounding(BigFloat,RoundNearest) do BigFloat("0.0938"), BigFloat("0.102") end - with_bigfloat_rounding(RoundDown) do + with_rounding(BigFloat,RoundDown) do @test BigFloat(0.1) == down @test BigFloat(0.1) != up end - with_bigfloat_rounding(RoundUp) do + with_rounding(BigFloat,RoundUp) do @test BigFloat(0.1) != down @test BigFloat(0.1) == up end diff --git a/test/rounding.jl b/test/rounding.jl index 0194dd3567b36..d672d32250366 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -16,7 +16,7 @@ d = prevfloat(1.) @test b - a === c # RoundToZero -with_rounding(RoundToZero) do +with_rounding(Float64,RoundToZero) do @test a + b === d @test - a - b === -d @test a - b === -c @@ -30,7 +30,7 @@ end @test b - a == c # RoundUp -with_rounding(RoundUp) do +with_rounding(Float64,RoundUp) do @test a + b === 1. @test - a - b === -d @test a - b === -c @@ -38,7 +38,7 @@ with_rounding(RoundUp) do end # RoundDown -with_rounding(RoundDown) do +with_rounding(Float64,RoundDown) do @test a + b === d @test - a - b === -1. @test a - b === -c @@ -59,7 +59,7 @@ d32 = prevfloat(1.0f0) @test b32 - a32 === c32 # RoundToZero -with_rounding(RoundToZero) do +with_rounding(Float32,RoundToZero) do @test a32 + b32 === d32 @test - a32 - b32 === -d32 @test a32 - b32 === -c32 @@ -73,7 +73,7 @@ end @test b32 - a32 == c32 # RoundUp -with_rounding(RoundUp) do +with_rounding(Float32,RoundUp) do @test a32 + b32 === 1.0f0 @test - a32 - b32 === -d32 @test a32 - b32 === -c32 @@ -81,7 +81,7 @@ with_rounding(RoundUp) do end # RoundDown -with_rounding(RoundDown) do +with_rounding(Float32,RoundDown) do @test a32 + b32 === d32 @test - a32 - b32 === -1.0f0 @test a32 - b32 === -c32