Skip to content

Commit

Permalink
add BitsFloat abstract type, leverage dispatch for rounding modes
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyrne committed Dec 11, 2013
1 parent 43d9445 commit e77e7eb
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 60 deletions.
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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,
Expand Down
21 changes: 4 additions & 17 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions base/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

Expand Down Expand Up @@ -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
--------------

Expand Down
6 changes: 3 additions & 3 deletions test/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions test/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit e77e7eb

Please sign in to comment.