Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: add BitsFloat abstract type, leverage dispatch for rounding modes #5007

Merged
merged 1 commit into from
Dec 19, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -49,14 +49,18 @@ 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
[#4782]: https://github.com/JuliaLang/julia/issues/4782
[#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
8 changes: 8 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
@@ -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

3 changes: 0 additions & 3 deletions base/exports.jl
Original file line number Diff line number Diff line change
@@ -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,
21 changes: 4 additions & 17 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
@@ -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
12 changes: 6 additions & 6 deletions base/rounding.jl
Original file line number Diff line number Diff line change
@@ -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

6 changes: 3 additions & 3 deletions doc/manual/integers-and-floating-point-numbers.rst
Original file line number Diff line number Diff line change
@@ -500,7 +500,7 @@ presented in the `IEEE 754 standard <http://en.wikipedia.org/wiki/IEEE_754-2008>
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
34 changes: 13 additions & 21 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
@@ -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
--------------

6 changes: 3 additions & 3 deletions test/mpfr.jl
Original file line number Diff line number Diff line change
@@ -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
12 changes: 6 additions & 6 deletions test/rounding.jl
Original file line number Diff line number Diff line change
@@ -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,15 +30,15 @@ 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
@test b - a === c
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,15 +73,15 @@ 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
@test b32 - a32 === c32
end

# RoundDown
with_rounding(RoundDown) do
with_rounding(Float32,RoundDown) do
@test a32 + b32 === d32
@test - a32 - b32 === -1.0f0
@test a32 - b32 === -c32