From f6e9bdf0918624a45a9b165bc4afdc05227efce6 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Tue, 16 Aug 2016 12:06:08 +0100 Subject: [PATCH] Document known problem with setrounding. Fixes the doc problem mentioned in #17926, but not the underlying problem. --- base/rounding.jl | 25 +++++++++++++++++-- .../integers-and-floating-point-numbers.rst | 8 ++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/base/rounding.jl b/base/rounding.jl index 43fe9565440e2..4571419584c05 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -100,12 +100,15 @@ end setrounding(T, mode) Set the rounding mode of floating point type `T`, controlling the rounding of basic -arithmetic functions ([`+`](:func:`+`), [`-`](:func:`-`), [`*`](:func:`*`), [`/`](:func:`/`) -and [`sqrt`](:func:`sqrt`)) and type conversion. +arithmetic functions ([`+`](:func:`+`), [`-`](:func:`-`), [`*`](:func:`*`), +[`/`](:func:`/`) and [`sqrt`](:func:`sqrt`)) 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` will change the rounding mode of `Float32`. See [`RoundingMode`](:obj:`RoundingMode`) for available modes. + """ setrounding(T::Type, mode) @@ -117,6 +120,8 @@ arithmetic functions ([`+`](:func:`+`), [`-`](:func:`-`), [`*`](:func:`*`), [`/` and [`sqrt`](:func:`sqrt`)) and type conversion. See [`RoundingMode`](:obj:`RoundingMode`) for available modes. + +**Warning**: This feature is still experimental, and may give unexpected or incorrect values. """ :rounding @@ -138,6 +143,22 @@ equivalent to: setrounding(T, old) See [`RoundingMode`](:obj:`RoundingMode`) 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{T}(f::Function, ::Type{T}, rounding::RoundingMode) old_rounding_raw = rounding_raw(T) diff --git a/doc/manual/integers-and-floating-point-numbers.rst b/doc/manual/integers-and-floating-point-numbers.rst index 36279871cc0f5..8ffdf7e745d08 100644 --- a/doc/manual/integers-and-floating-point-numbers.rst +++ b/doc/manual/integers-and-floating-point-numbers.rst @@ -507,12 +507,16 @@ rounded to an appropriate representable value, however, if wanted, the manner in which this rounding is done can be changed according to the rounding modes presented in the `IEEE 754 standard `_:: +.. doctest:: + + + julia> x = 1.1; y = 0.1; - julia> 1.1 + 0.1 + julia> x + y 1.2000000000000002 julia> setrounding(Float64,RoundDown) do - 1.1 + 0.1 + x + y end 1.2