From 86761e6b65ac553c25fc945d071e0da57ba92ff2 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Wed, 29 Oct 2014 10:40:37 +0000 Subject: [PATCH 1/3] add RoundingMode argument to convert --- base/constants.jl | 5 ++ base/mpfr.jl | 13 ++++- base/rounding.jl | 17 +++++-- doc/helpdb.jl | 119 ++++++++++++++++++++++++++++++++++++-------- doc/stdlib/base.rst | 44 +++++++++++++++- test/rounding.jl | 26 ++++++++++ 6 files changed, 196 insertions(+), 28 deletions(-) diff --git a/base/constants.jl b/base/constants.jl index 95003e41213db..2f2c57de77052 100644 --- a/base/constants.jl +++ b/base/constants.jl @@ -13,6 +13,11 @@ convert(::Type{Float16}, x::MathConst) = float16(float32(x)) convert{T<:Real}(::Type{Complex{T}}, x::MathConst) = convert(Complex{T}, convert(T,x)) convert{T<:Integer}(::Type{Rational{T}}, x::MathConst) = convert(Rational{T}, float64(x)) +stagedfunction convert{T<:Union(Float32,Float64),s}(t::Type{T},c::MathConst{s},r::RoundingMode) + f = convert(T,big(c()),r()) + :($f) +end + =={s}(::MathConst{s}, ::MathConst{s}) = true ==(::MathConst, ::MathConst) = false diff --git a/base/mpfr.jl b/base/mpfr.jl index 5fb6f15549f49..167aef0fd53a7 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -20,6 +20,8 @@ import realmin, realmax, get_rounding, set_rounding, maxintfloat, widen, significand, frexp +import Base.Rounding: get_rounding_raw, set_rounding_raw + import Base.GMP: ClongMax, CulongMax, CdoubleMax import Base.Math.lgamma_r @@ -118,6 +120,11 @@ convert(::Type{Float64}, x::BigFloat) = convert(::Type{Float32}, x::BigFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{BigFloat},Int32), &x, ROUNDING_MODE[end]) +convert(::Type{Float64}, x::BigFloat, r::RoundingMode) = + ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{BigFloat},Int32), &x, to_mpfr(r)) +convert(::Type{Float32}, x::BigFloat, r::RoundingMode) = + ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{BigFloat},Int32), &x, to_mpfr(r)) + convert(::Type{Integer}, x::BigFloat) = convert(BigInt, x) promote_rule{T<:Real}(::Type{BigFloat}, ::Type{T}) = BigFloat @@ -597,8 +604,10 @@ function from_mpfr(c::Integer) RoundingMode(c) end -get_rounding(::Type{BigFloat}) = from_mpfr(ROUNDING_MODE[end]) -set_rounding(::Type{BigFloat},r::RoundingMode) = ROUNDING_MODE[end] = to_mpfr(r) +get_rounding_raw(::Type{BigFloat}) = ROUNDING_MODE[end] +set_rounding_raw(::Type{BigFloat},i::Integer) = ROUNDING_MODE[end] = i +get_rounding(::Type{BigFloat}) = from_mpfr(get_rounding_raw(BigFloat)) +set_rounding(::Type{BigFloat},r::RoundingMode) = set_rounding_raw(BigFloat,to_mpfr(r)) function copysign(x::BigFloat, y::BigFloat) z = BigFloat() diff --git a/base/rounding.jl b/base/rounding.jl index 20f8d28329bb1..c7f778944c1d8 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -1,6 +1,8 @@ module Rounding include("fenv_constants.jl") +import Base: convert + export RoundingMode, RoundNearest, RoundToZero, RoundUp, RoundDown, RoundFromZero, get_rounding, set_rounding, with_rounding @@ -34,17 +36,24 @@ function from_fenv(r::Integer) end end -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, ())) +set_rounding_raw{T<:Union(Float32,Float64)}(::Type{T},i::Integer) = ccall(:fesetround, Cint, (Cint,), i) +get_rounding_raw{T<:Union(Float32,Float64)}(::Type{T}) = ccall(:fegetround, Cint, ()) + +set_rounding{T<:Union(Float32,Float64)}(::Type{T},r::RoundingMode) = set_rounding_raw(T,to_fenv(r)) +get_rounding{T<:Union(Float32,Float64)}(::Type{T}) = from_fenv(get_rounding_raw(T)) function with_rounding{T}(f::Function, ::Type{T}, rounding::RoundingMode) - old_rounding = get_rounding(T) + old_rounding_raw = get_rounding_raw(T) set_rounding(T,rounding) try return f() finally - set_rounding(T,old_rounding) + set_rounding_raw(T,old_rounding_raw) end end +convert(::Type{Float32},x::Float64,r::RoundingMode) = with_rounding(Float64,r) do + convert(Float32,x) +end + end #module diff --git a/doc/helpdb.jl b/doc/helpdb.jl index 61bbb25100b68..7aa438e5cbee2 100644 --- a/doc/helpdb.jl +++ b/doc/helpdb.jl @@ -369,11 +369,44 @@ Any[ "), -("Base","convert","convert(type, x) +("Base","convert","convert(T, x[, r::RoundingMode]) - Try to convert \"x\" to the given type. Conversion to a different - numeric type will raise an \"InexactError\" if \"x\" cannot be - represented exactly in the new type. + Convert the \"x\" to a value of type \"T\". + + If \"T\" is an \"Integer\" type, an \"InexactError\" will be raised + if \"x\" is not representable by \"T\", for example if \"x\" is not + integer-valued, or is outside the range supported by \"T\". + + julia> convert(Int, 3.0) + 3 + + julia> convert(Int, 3.5) + ERROR: InexactError() + in convert at int.jl:185 + + If \"T\" is a \"FloatingPoint\" or \"Rational\" type, then it will + return the closest value to \"x\" representable by \"T\". If \"T\" + is a \"FloatingPoint\" type that is smaller than that of \"x\", + then the method accepts an optional argument \"r\" which determines + the direction of rounding. + + julia> x = 1/3 + 0.3333333333333333 + + julia> convert(Float32, x) + 0.33333334f0 + + julia> convert(Rational{Int32}, x) + 1//3 + + julia> convert(Rational{Int64}, x) + 6004799503160661//18014398509481984 + + julia> convert(Float32, x, RoundDown) + 0.3333333f0 + + julia> convert(Float32, x, RoundUp) + 0.33333334f0 "), @@ -564,10 +597,10 @@ Any[ "), -("Base","fieldtype","fieldtype(value, name::Symbol) +("Base","fieldtype","fieldtype(type, name::Symbol | index::Int) - Determine the declared type of a named field in a value of - composite type. + Determine the declared type of a field (specified by name or index) + in a composite type. "), @@ -1801,15 +1834,15 @@ Any[ ("Base","is_valid_ascii","is_valid_ascii(s) -> Bool - Returns true if the string or byte vector is valid ASCII, false - otherwise. + Returns true if the argument (\"ASCIIString\", \"UTF8String\", or + byte vector) is valid ASCII, false otherwise. "), ("Base","is_valid_utf8","is_valid_utf8(s) -> Bool - Returns true if the string or byte vector is valid UTF-8, false - otherwise. + Returns true if the argument (\"ASCIIString\", \"UTF8String\", or + byte vector) is valid UTF-8, false otherwise. "), @@ -2246,7 +2279,8 @@ Any[ ("Base","is_valid_utf16","is_valid_utf16(s) -> Bool - Returns true if the string or \"Uint16\" array is valid UTF-16. + Returns true if the argument (\"UTF16String\" or \"Uint16\" array) + is valid UTF-16. "), @@ -3208,11 +3242,11 @@ Any[ ("Base","writedlm","writedlm(f, A, delim='t') - Write \"A\" (a vector, matrix or an iterable collection of - iterable rows) as text to \"f\" (either a filename string or an - \"IO\" stream) using the given delimeter \"delim\" (which defaults - to tab, but can be any printable Julia object, typically a \"Char\" - or \"String\"). + Write \"A\" (a vector, matrix or an iterable collection of iterable + rows) as text to \"f\" (either a filename string or an \"IO\" + stream) using the given delimeter \"delim\" (which defaults to tab, + but can be any printable Julia object, typically a \"Char\" or + \"String\"). For example, two vectors \"x\" and \"y\" of the same length can be written as two columns of tab-delimited text to \"f\" by either @@ -6070,9 +6104,22 @@ popdisplay(d::Display) "), -("Base","cat","cat(dim, A...) +("Base","cat","cat(dims, A...) - Concatenate the input arrays along the specified dimension + Concatenate the input arrays along the specified dimensions in the + iterable \"dims\". For dimensions not in \"dims\", all input arrays + should have the same size, which will also be the size of the + output array along that dimension. For dimensions in \"dims\", the + size of the output array is the sum of the sizes of the input + arrays along that dimension. If \"dims\" is a single number, the + different arrays are tightly stacked along that dimension. If + \"dims\" is an iterable containing several dimensions, this allows + to construct block diagonal matrices and their higher-dimensional + analogues by simultaneously increasing several dimensions for every + new input array and putting zero blocks elsewhere. For example, + *cat([1,2], matrices...)* builds a block diagonal matrix, i.e. a + block matrix with *matrices[1]*, *matrices[2]*, ... as diagonal + blocks and matching zero blocks away from the diagonal. "), @@ -11759,7 +11806,39 @@ Millisecond(v) \"A\". This includes zeros that are explicitly stored in the sparse matrix. The returned vector points directly to the internal nonzero storage of \"A\", and any modifications to the returned vector will - mutate \"A\" as well. + mutate \"A\" as well. See \"rowvals(A)\" and \"nzrange(A, col)\". + +"), + +("Base","rowvals","rowvals(A) + + Return a vector of the row indices of \"A\", and any modifications + to the returned vector will mutate \"A\" as well. Given the + internal storage format of sparse matrices, providing access to how + the row indices are stored internally can be useful in conjuction + with iterating over structural nonzero values. See \"nonzeros(A)\" + and \"nzrange(A, col)\". + +"), + +("Base","nzrange","nzrange(A, col) + + Return the range of indices to the structural nonzero values of a + sparse matrix column. In conjunction with \"nonzeros(A)\" and + \"rowvals(A)\", this allows for convenient iterating over a sparse + matrix + + A = sparse(I,J,V) + rows = rowvals(A) + vals = nonzeros(A) + m, n = size(A) + for i = 1:n + for j in nzrange(A, i) + row = rows[j] + val = vals[j] + # perform sparse wizardry... + end + end "), diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index aadda50d0ed2f..fede8dd5e7f36 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -233,9 +233,49 @@ All Objects With a single symbol argument, tests whether a global variable with that name is defined in ``current_module()``. -.. function:: convert(type, x) +.. function:: convert(T, x [, r::RoundingMode]) + + Convert the ``x`` to a value of type ``T``. + + If ``T`` is an ``Integer`` type, an ``InexactError`` will be raised if + ``x`` is not representable by ``T``, for example if ``x`` is not + integer-valued, or is outside the range supported by ``T``. + + .. doctest:: + + julia> convert(Int, 3.0) + 3 + + julia> convert(Int, 3.5) + ERROR: InexactError() + in convert at int.jl:185 + + If ``T`` is a ``FloatingPoint`` or ``Rational`` type, then it will return + the closest value to ``x`` representable by ``T``. If ``T`` is a + ``FloatingPoint`` type that is smaller than that of ``x``, then the method + accepts an optional argument ``r`` which determines the direction of + rounding. + + .. doctest:: + + julia> x = 1/3 + 0.3333333333333333 + + julia> convert(Float32, x) + 0.33333334f0 + + julia> convert(Rational{Int32}, x) + 1//3 + + julia> convert(Rational{Int64}, x) + 6004799503160661//18014398509481984 + + julia> convert(Float32, x, RoundDown) + 0.3333333f0 + + julia> convert(Float32, x, RoundUp) + 0.33333334f0 - Try to convert ``x`` to the given type. Conversion to a different numeric type will raise an ``InexactError`` if ``x`` cannot be represented exactly in the new type. .. function:: promote(xs...) diff --git a/test/rounding.jl b/test/rounding.jl index d672d32250366..df842dd588073 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -87,3 +87,29 @@ with_rounding(Float32,RoundDown) do @test a32 - b32 === -c32 @test b32 - a32 === c32 end + +# convert with rounding +for v = [sqrt(2),-1/3,nextfloat(1.0),prevfloat(1.0),nextfloat(-1.0),prevfloat(-1.0)] + pn = convert(Float32,v) + @test pn == convert(Float32,v,RoundNearest) + pz = convert(Float32,v,RoundToZero) + pd = convert(Float32,v,RoundDown) + pu = convert(Float32,v,RoundUp) + @test pn == pd || pn == pu + @test v > 0 ? pz == pd : pz == pu + @test pu - pd == eps(pz) +end + +for T in [Float32,Float64] + for v in [sqrt(big(2.0)),-big(1.0)/big(3.0),nextfloat(big(1.0)), + pi,e,eulergamma,catalan,golden] + pn = convert(T,v) + @test pn == convert(T,v,RoundNearest) + pz = convert(T,v,RoundToZero) + pd = convert(T,v,RoundDown) + pu = convert(T,v,RoundUp) + @test pn == pd || pn == pu + @test v > 0 ? pz == pd : pz == pu + @test pu - pd == eps(pz) + end +end From 560b21a70d0ef37f8df8af23abafc540c2c62de4 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Wed, 29 Oct 2014 12:37:41 +0000 Subject: [PATCH 2/3] use explicit checks for rounded convert --- base/rounding.jl | 27 +++++++++++++++++++++++++-- test/rounding.jl | 14 ++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/base/rounding.jl b/base/rounding.jl index c7f778944c1d8..8e9fceb484abf 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -52,8 +52,31 @@ function with_rounding{T}(f::Function, ::Type{T}, rounding::RoundingMode) end end -convert(::Type{Float32},x::Float64,r::RoundingMode) = with_rounding(Float64,r) do - convert(Float32,x) + +# Should be equivalent to: +# convert(::Type{Float32},x::Float64,r::RoundingMode) = with_rounding(Float64,r) do +# convert(Float32,x) +# end +# but explicit checks are currently quicker (~20x). +# Assumes current rounding mode is RoundToNearest + +convert(::Type{Float32},x::Float64,r::RoundingMode{:TiesToEven}) = convert(Float32,x) + +function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardNegative}) + y = convert(Float32,x) + y > x ? prevfloat(y) : y +end +function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardPositive}) + y = convert(Float32,x) + y < x ? nextfloat(y) : y +end +function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardZero}) + y = convert(Float32,x) + if x > 0.0 + y > x ? prevfloat(y) : y + else + y < x ? nextfloat(y) : y + end end end #module diff --git a/test/rounding.jl b/test/rounding.jl index df842dd588073..62b167efab19b 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -89,12 +89,17 @@ with_rounding(Float32,RoundDown) do end # convert with rounding -for v = [sqrt(2),-1/3,nextfloat(1.0),prevfloat(1.0),nextfloat(-1.0),prevfloat(-1.0)] +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 = convert(Float32,v) @test pn == convert(Float32,v,RoundNearest) pz = convert(Float32,v,RoundToZero) + @test pz == with_rounding(()->convert(Float32,v), Float64, RoundToZero) pd = convert(Float32,v,RoundDown) + @test pd == with_rounding(()->convert(Float32,v), Float64, RoundDown) pu = convert(Float32,v,RoundUp) + @test pu == with_rounding(()->convert(Float32,v), Float64, RoundUp) + @test pn == pd || pn == pu @test v > 0 ? pz == pd : pz == pu @test pu - pd == eps(pz) @@ -102,12 +107,17 @@ end for T in [Float32,Float64] for v in [sqrt(big(2.0)),-big(1.0)/big(3.0),nextfloat(big(1.0)), - pi,e,eulergamma,catalan,golden] + prevfloat(big(1.0)),nextfloat(big(0.0)),prevfloat(big(0.0)), + pi,e,eulergamma,catalan,golden,] pn = convert(T,v) @test pn == convert(T,v,RoundNearest) pz = convert(T,v,RoundToZero) + @test pz == with_rounding(()->convert(T,v), BigFloat, RoundToZero) pd = convert(T,v,RoundDown) + @test pd == with_rounding(()->convert(T,v), BigFloat, RoundDown) pu = convert(T,v,RoundUp) + @test pu == with_rounding(()->convert(T,v), BigFloat, RoundUp) + @test pn == pd || pn == pu @test v > 0 ? pz == pd : pz == pu @test pu - pd == eps(pz) From c421d1430632a93895721afb626fcb664e664174 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Thu, 30 Oct 2014 09:46:03 +0000 Subject: [PATCH 3/3] move rounding conversions from convert to call --- base/constants.jl | 4 ++-- base/mpfr.jl | 4 ++-- base/rounding.jl | 12 +++++------- doc/helpdb.jl | 15 +++------------ doc/stdlib/base.rst | 16 +++------------- test/rounding.jl | 20 ++++++++++---------- 6 files changed, 25 insertions(+), 46 deletions(-) diff --git a/base/constants.jl b/base/constants.jl index 2f2c57de77052..c5ac448fe8ef2 100644 --- a/base/constants.jl +++ b/base/constants.jl @@ -13,8 +13,8 @@ convert(::Type{Float16}, x::MathConst) = float16(float32(x)) convert{T<:Real}(::Type{Complex{T}}, x::MathConst) = convert(Complex{T}, convert(T,x)) convert{T<:Integer}(::Type{Rational{T}}, x::MathConst) = convert(Rational{T}, float64(x)) -stagedfunction convert{T<:Union(Float32,Float64),s}(t::Type{T},c::MathConst{s},r::RoundingMode) - f = convert(T,big(c()),r()) +stagedfunction call{T<:Union(Float32,Float64),s}(t::Type{T},c::MathConst{s},r::RoundingMode) + f = T(big(c()),r()) :($f) end diff --git a/base/mpfr.jl b/base/mpfr.jl index 167aef0fd53a7..31f95cea7d849 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -120,9 +120,9 @@ convert(::Type{Float64}, x::BigFloat) = convert(::Type{Float32}, x::BigFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{BigFloat},Int32), &x, ROUNDING_MODE[end]) -convert(::Type{Float64}, x::BigFloat, r::RoundingMode) = +call(::Type{Float64}, x::BigFloat, r::RoundingMode) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{BigFloat},Int32), &x, to_mpfr(r)) -convert(::Type{Float32}, x::BigFloat, r::RoundingMode) = +call(::Type{Float32}, x::BigFloat, r::RoundingMode) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{BigFloat},Int32), &x, to_mpfr(r)) convert(::Type{Integer}, x::BigFloat) = convert(BigInt, x) diff --git a/base/rounding.jl b/base/rounding.jl index 8e9fceb484abf..d9ed8f8d01d11 100644 --- a/base/rounding.jl +++ b/base/rounding.jl @@ -1,8 +1,6 @@ module Rounding include("fenv_constants.jl") -import Base: convert - export RoundingMode, RoundNearest, RoundToZero, RoundUp, RoundDown, RoundFromZero, get_rounding, set_rounding, with_rounding @@ -54,23 +52,23 @@ end # Should be equivalent to: -# convert(::Type{Float32},x::Float64,r::RoundingMode) = with_rounding(Float64,r) do +# call(::Type{Float32},x::Float64,r::RoundingMode) = with_rounding(Float64,r) do # convert(Float32,x) # end # but explicit checks are currently quicker (~20x). # Assumes current rounding mode is RoundToNearest -convert(::Type{Float32},x::Float64,r::RoundingMode{:TiesToEven}) = convert(Float32,x) +call(::Type{Float32},x::Float64,r::RoundingMode{:TiesToEven}) = convert(Float32,x) -function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardNegative}) +function call(::Type{Float32},x::Float64,r::RoundingMode{:TowardNegative}) y = convert(Float32,x) y > x ? prevfloat(y) : y end -function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardPositive}) +function call(::Type{Float32},x::Float64,r::RoundingMode{:TowardPositive}) y = convert(Float32,x) y < x ? nextfloat(y) : y end -function convert(::Type{Float32},x::Float64,r::RoundingMode{:TowardZero}) +function call(::Type{Float32},x::Float64,r::RoundingMode{:TowardZero}) y = convert(Float32,x) if x > 0.0 y > x ? prevfloat(y) : y diff --git a/doc/helpdb.jl b/doc/helpdb.jl index 7aa438e5cbee2..a7836b862fafb 100644 --- a/doc/helpdb.jl +++ b/doc/helpdb.jl @@ -369,9 +369,9 @@ Any[ "), -("Base","convert","convert(T, x[, r::RoundingMode]) +("Base","convert","convert(T, x) - Convert the \"x\" to a value of type \"T\". + Convert \"x\" to a value of type \"T\". If \"T\" is an \"Integer\" type, an \"InexactError\" will be raised if \"x\" is not representable by \"T\", for example if \"x\" is not @@ -385,10 +385,7 @@ Any[ in convert at int.jl:185 If \"T\" is a \"FloatingPoint\" or \"Rational\" type, then it will - return the closest value to \"x\" representable by \"T\". If \"T\" - is a \"FloatingPoint\" type that is smaller than that of \"x\", - then the method accepts an optional argument \"r\" which determines - the direction of rounding. + return the closest value to \"x\" representable by \"T\". julia> x = 1/3 0.3333333333333333 @@ -402,12 +399,6 @@ Any[ julia> convert(Rational{Int64}, x) 6004799503160661//18014398509481984 - julia> convert(Float32, x, RoundDown) - 0.3333333f0 - - julia> convert(Float32, x, RoundUp) - 0.33333334f0 - "), ("Base","promote","promote(xs...) diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index fede8dd5e7f36..b23bacda4d4ca 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -233,9 +233,9 @@ All Objects With a single symbol argument, tests whether a global variable with that name is defined in ``current_module()``. -.. function:: convert(T, x [, r::RoundingMode]) +.. function:: convert(T, x) - Convert the ``x`` to a value of type ``T``. + Convert ``x`` to a value of type ``T``. If ``T`` is an ``Integer`` type, an ``InexactError`` will be raised if ``x`` is not representable by ``T``, for example if ``x`` is not @@ -251,10 +251,7 @@ All Objects in convert at int.jl:185 If ``T`` is a ``FloatingPoint`` or ``Rational`` type, then it will return - the closest value to ``x`` representable by ``T``. If ``T`` is a - ``FloatingPoint`` type that is smaller than that of ``x``, then the method - accepts an optional argument ``r`` which determines the direction of - rounding. + the closest value to ``x`` representable by ``T``. .. doctest:: @@ -270,13 +267,6 @@ All Objects julia> convert(Rational{Int64}, x) 6004799503160661//18014398509481984 - julia> convert(Float32, x, RoundDown) - 0.3333333f0 - - julia> convert(Float32, x, RoundUp) - 0.33333334f0 - - .. function:: promote(xs...) Convert all arguments to their common promotion type (if any), and return them all (as a tuple). diff --git a/test/rounding.jl b/test/rounding.jl index 62b167efab19b..e406f22b72fc5 100644 --- a/test/rounding.jl +++ b/test/rounding.jl @@ -91,13 +91,13 @@ end # convert with rounding 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 = convert(Float32,v) - @test pn == convert(Float32,v,RoundNearest) - pz = convert(Float32,v,RoundToZero) + pn = Float32(v,RoundNearest) + @test pn == convert(Float32,v) + pz = Float32(v,RoundToZero) @test pz == with_rounding(()->convert(Float32,v), Float64, RoundToZero) - pd = convert(Float32,v,RoundDown) + pd = Float32(v,RoundDown) @test pd == with_rounding(()->convert(Float32,v), Float64, RoundDown) - pu = convert(Float32,v,RoundUp) + pu = Float32(v,RoundUp) @test pu == with_rounding(()->convert(Float32,v), Float64, RoundUp) @test pn == pd || pn == pu @@ -109,13 +109,13 @@ for T in [Float32,Float64] for v in [sqrt(big(2.0)),-big(1.0)/big(3.0),nextfloat(big(1.0)), prevfloat(big(1.0)),nextfloat(big(0.0)),prevfloat(big(0.0)), pi,e,eulergamma,catalan,golden,] - pn = convert(T,v) - @test pn == convert(T,v,RoundNearest) - pz = convert(T,v,RoundToZero) + pn = T(v,RoundNearest) + @test pn == convert(T,v) + pz = T(v,RoundToZero) @test pz == with_rounding(()->convert(T,v), BigFloat, RoundToZero) - pd = convert(T,v,RoundDown) + pd = T(v,RoundDown) @test pd == with_rounding(()->convert(T,v), BigFloat, RoundDown) - pu = convert(T,v,RoundUp) + pu = T(v,RoundUp) @test pu == with_rounding(()->convert(T,v), BigFloat, RoundUp) @test pn == pd || pn == pu