From 27ed156ac5c653ad7f214b709878ca69a76bc47c Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Mon, 19 Nov 2018 21:19:19 +1100 Subject: [PATCH] Make precision a keyword argument, improve handling of rounding mode. (#29157) * Improve handling of precision and rounding mode arguments in BigFloat constructors. This makes a few changes to avoid unnecessarily calling `setrounding` and `setprecision`. It also changes `precision` to be a keyword argument (though does not yet deprecate the old behaviour). --- NEWS.md | 4 +- base/deprecated.jl | 5 + base/irrationals.jl | 12 +- base/mpfr.jl | 401 ++++++++++++++++---------------- base/parse.jl | 8 +- base/sysimg.jl | 8 +- doc/src/base/numbers.md | 5 +- stdlib/Random/src/generation.jl | 4 +- test/mpfr.jl | 2 +- 9 files changed, 231 insertions(+), 218 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4f785147c04981..812bf523cef8e8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,7 +11,9 @@ Language changes ---------------- * the constructor `BigFloat(::BigFloat)` now respects the global precision setting and always - returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127]). + returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127]). The optional + `precision` argument to override the global setting is now a keyword instead of positional + argument ([#29157]). * Parser inputs ending with a comma are now consistently treated as incomplete. Previously they were sometimes parsed as tuples, depending on whitespace ([#28506]). * `Regex` now behave like a scalar when used in broadcasting ([#29913]). diff --git a/base/deprecated.jl b/base/deprecated.jl index 9c370d5d6213a8..7d765ae86a135b 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -168,4 +168,9 @@ function promote_eltype_op end one(::CartesianIndex{N}) where {N} = one(CartesianIndex{N}) one(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 1, Val(N))) +MPFR.BigFloat(x, prec::Int) = BigFloat(x; precision=prec) +MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) = BigFloat(x, rounding; precision=prec) +MPFR.BigFloat(x::Real, prec::Int) = BigFloat(x; precision=prec) +MPFR.BigFloat(x::Real, prec::Int, rounding::RoundingMode) = BigFloat(x, rounding; precision=prec) + # END 1.0 deprecations diff --git a/base/irrationals.jl b/base/irrationals.jl index dd47c402f1ce6f..efce4669694c56 100644 --- a/base/irrationals.jl +++ b/base/irrationals.jl @@ -147,14 +147,18 @@ macro irrational(sym, val, def) esym = esc(sym) qsym = esc(Expr(:quote, sym)) bigconvert = isa(def,Symbol) ? quote - function Base.BigFloat(::Irrational{$qsym}) - c = BigFloat() + function Base.BigFloat(::Irrational{$qsym}, r::MPFR.MPFRRoundingMode=MPFR.ROUNDING_MODE[]; precision=precision(BigFloat)) + c = BigFloat(;precision=precision) ccall(($(string("mpfr_const_", def)), :libmpfr), - Cint, (Ref{BigFloat}, Int32), c, MPFR.ROUNDING_MODE[]) + Cint, (Ref{BigFloat}, MPFR.MPFRRoundingMode), c, r) return c end end : quote - Base.BigFloat(::Irrational{$qsym}) = $(esc(def)) + function Base.BigFloat(::Irrational{$qsym}; precision=precision(BigFloat)) + setprecision(BigFloat, precision) do + $(esc(def)) + end + end end quote const $esym = Irrational{$qsym}() diff --git a/base/mpfr.jl b/base/mpfr.jl index 504d63ee59a1fd..3d3b8ed3e3f1ad 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -39,8 +39,47 @@ function __init__() nothing end -const ROUNDING_MODE = Ref{Cint}(0) # actually an Enum, defined by `to_mpfr` -const DEFAULT_PRECISION = Ref{Int}(256) +""" + MPFR.MPFRRoundingMode + +Matches the `mpfr_rnd_t` enum provided by MPFR, see +https://www.mpfr.org/mpfr-current/mpfr.html#Rounding-Modes + +This is for internal use, and ensures that `ROUNDING_MODE[]` is type-stable. +""" +@enum MPFRRoundingMode begin + MPFRRoundNearest + MPFRRoundToZero + MPFRRoundUp + MPFRRoundDown + MPFRRoundFromZero + MPFRRoundFaithful +end + +convert(::Type{MPFRRoundingMode}, ::RoundingMode{:Nearest}) = MPFRRoundNearest +convert(::Type{MPFRRoundingMode}, ::RoundingMode{:ToZero}) = MPFRRoundToZero +convert(::Type{MPFRRoundingMode}, ::RoundingMode{:Up}) = MPFRRoundUp +convert(::Type{MPFRRoundingMode}, ::RoundingMode{:Down}) = MPFRRoundDown +convert(::Type{MPFRRoundingMode}, ::RoundingMode{:FromZero}) = MPFRRoundFromZero + +function convert(::Type{RoundingMode}, r::MPFRRoundingMode) + if r == MPFRRoundNearest + return RoundNearest + elseif r == MPFRRoundToZero + return RoundToZero + elseif r == MPFRRoundUp + return RoundUp + elseif r == MPFRRoundDown + return RoundDown + elseif r == MPFRRoundFromZero + return RoundFromZero + else + throw(ArgumentError("invalid MPFR rounding mode code: $c")) + end +end + +const ROUNDING_MODE = Ref{MPFRRoundingMode}(MPFRRoundNearest) +const DEFAULT_PRECISION = Ref{Clong}(256) # Basic type and initialization definitions @@ -69,17 +108,23 @@ mutable struct BigFloat <: AbstractFloat return new(prec, sign, exp, pointer(d), d) end - function BigFloat() - prec::Clong = precision(BigFloat) - nb = ccall((:mpfr_custom_get_size,:libmpfr), Csize_t, (Clong,), prec) + function BigFloat(; precision::Integer=DEFAULT_PRECISION[]) + nb = ccall((:mpfr_custom_get_size,:libmpfr), Csize_t, (Clong,), precision) nb = (nb + Core.sizeof(Limb) - 1) ÷ Core.sizeof(Limb) # align to number of Limb allocations required for this #d = Vector{Limb}(undef, nb) d = _string_n(nb * Core.sizeof(Limb)) EXP_NAN = Clong(1) - Clong(typemax(Culong) >> 1) - return _BigFloat(prec, one(Cint), EXP_NAN, d) # +NAN + return _BigFloat(Clong(precision), one(Cint), EXP_NAN, d) # +NAN end end +rounding_raw(::Type{BigFloat}) = ROUNDING_MODE[] +setrounding_raw(::Type{BigFloat}, r::MPFRRoundingMode) = ROUNDING_MODE[]=r + +rounding(::Type{BigFloat}) = convert(RoundingMode, rounding_raw(BigFloat)) +setrounding(::Type{BigFloat},r::RoundingMode) = setrounding_raw(BigFloat, convert(MPFRRoundingMode, r)) + + # overload the definition of unsafe_convert to ensure that `x.d` is assigned # it may have been dropped in the event that the BigFloat was serialized Base.unsafe_convert(::Type{Ref{BigFloat}}, x::Ptr{BigFloat}) = x @@ -91,39 +136,53 @@ Base.unsafe_convert(::Type{Ref{BigFloat}}, x::Ptr{BigFloat}) = x return convert(Ptr{BigFloat}, Base.pointer_from_objref(x)) end - """ - BigFloat(x) + BigFloat(x::Union{Real, AbstractString} [, rounding::RoundingMode=rounding(BigFloat)]; [precision::Integer=precision(BigFloat)]) + +Create an arbitrary precision floating point number from `x`, with precision +`precision`. The `rounding` argument specifies the direction in which the result should be +rounded if the conversion cannot be done exactly. If not provided, these are set by the current global values. -Create an arbitrary precision floating point number. `x` may be an [`Integer`](@ref), a -[`Float64`](@ref) or a [`BigInt`](@ref). The usual mathematical operators are defined for -this type, and results are promoted to a [`BigFloat`](@ref). +`BigFloat(x::Real)` is the same as `convert(BigFloat,x)`, except if `x` itself is already +`BigFloat`, in which case it will return a value with the precision set to the current +global precision; `convert` will always return `x`. -Note that because decimal literals are converted to floating point numbers when parsed, -`BigFloat(2.1)` may not yield what you expect. You may instead prefer to initialize -constants from strings via [`parse`](@ref), or using the `big` string literal. +`BigFloat(x::AbstractString)` is identical to [`parse`](@ref). This is provided for +convenience since decimal literals are converted to `Float64` when parsed, so +`BigFloat(2.1)` may not yield what you expect. ```jldoctest -julia> BigFloat(2.1) +julia> BigFloat(2.1) # 2.1 here is a Float64 2.100000000000000088817841970012523233890533447265625 -julia> big"2.1" +julia> BigFloat("2.1") # the closest BigFloat to 2.1 2.099999999999999999999999999999999999999999999999999999999999999999999999999986 + +julia> BigFloat("2.1", RoundUp) +2.100000000000000000000000000000000000000000000000000000000000000000000000000021 + +julia> BigFloat("2.1", RoundUp, precision=128) +2.100000000000000000000000000000000000007 ``` + +# See also +- [`@big_str`](@ref) +- [`rounding`](@ref) and [`setrounding`](@ref) +- [`precision`](@ref) and [`setprecision`](@ref) """ -BigFloat(x) +BigFloat(x, r::RoundingMode) widen(::Type{Float64}) = BigFloat widen(::Type{BigFloat}) = BigFloat -function BigFloat(x::BigFloat) - if precision(BigFloat) == precision(x) - x +function BigFloat(x::BigFloat, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) + if precision == MPFR.precision(x) + return x else - z = BigFloat() - ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), - z, x, ROUNDING_MODE[]) - z + z = BigFloat(;precision=precision) + ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), + z, x, r) + return z end end @@ -131,115 +190,94 @@ end # convert to BigFloat for (fJ, fC) in ((:si,:Clong), (:ui,:Culong)) @eval begin - function BigFloat(x::($fC)) - z = BigFloat() - ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ref{BigFloat}, $fC, Int32), z, x, ROUNDING_MODE[]) + function BigFloat(x::($fC), r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) + z = BigFloat(;precision=precision) + ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ref{BigFloat}, $fC, MPFRRoundingMode), z, x, r) return z end end end -function BigFloat(x::Float64) - z = BigFloat() - ccall((:mpfr_set_d, :libmpfr), Int32, (Ref{BigFloat}, Float64, Int32), z, x, ROUNDING_MODE[]) +function BigFloat(x::Float64, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) + z = BigFloat(;precision=precision) + ccall((:mpfr_set_d, :libmpfr), Int32, (Ref{BigFloat}, Float64, MPFRRoundingMode), z, x, r) if isnan(x) && signbit(x) != signbit(z) z.sign = -z.sign end return z end -function BigFloat(x::BigInt) - z = BigFloat() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigInt}, Int32), z, x, ROUNDING_MODE[]) +function BigFloat(x::BigInt, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) + z = BigFloat(;precision=precision) + ccall((:mpfr_set_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigInt}, MPFRRoundingMode), z, x, r) return z end -BigFloat(x::Integer) = BigFloat(BigInt(x)) +BigFloat(x::Integer, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(BigInt(x), r; precision=precision) + +BigFloat(x::Union{Bool,Int8,Int16,Int32}, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(convert(Clong, x), r; precision=precision) +BigFloat(x::Union{UInt8,UInt16,UInt32}, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(convert(Culong, x), r; precision=precision) -BigFloat(x::Union{Bool,Int8,Int16,Int32}) = BigFloat(convert(Clong, x)) -BigFloat(x::Union{UInt8,UInt16,UInt32}) = BigFloat(convert(Culong, x)) +BigFloat(x::Union{Float16,Float32}, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(Float64(x), r; precision=precision) -BigFloat(x::Union{Float16,Float32}) = BigFloat(Float64(x)) -BigFloat(x::Rational) = BigFloat(numerator(x)) / BigFloat(denominator(x)) +BigFloat(x::Rational, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(numerator(x), r; precision=precision) / BigFloat(denominator(x), r ;precision=precision) -function tryparse(::Type{BigFloat}, s::AbstractString; base::Integer = 0) +function tryparse(::Type{BigFloat}, s::AbstractString; base::Integer=0, precision::Integer=DEFAULT_PRECISION[], rounding::MPFRRoundingMode=ROUNDING_MODE[]) !isempty(s) && isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base = base) - z = BigFloat() - err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ref{BigFloat}, Cstring, Int32, Int32), z, s, base, ROUNDING_MODE[]) + z = BigFloat(precision=precision) + err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ref{BigFloat}, Cstring, Int32, MPFRRoundingMode), z, s, base, rounding) err == 0 ? z : nothing end +BigFloat(x::AbstractString, r::MPFRRoundingMode=ROUNDING_MODE[]; precision::Integer=DEFAULT_PRECISION[]) = + parse(BigFloat, x; precision=precision, rounding=r) + Rational(x::BigFloat) = convert(Rational{BigInt}, x) AbstractFloat(x::BigInt) = BigFloat(x) float(::Type{BigInt}) = BigFloat -# generic constructor with arbitrary precision: -""" - BigFloat(x, prec::Int) - -Create a representation of `x` as a [`BigFloat`](@ref) with precision `prec`. -""" -function BigFloat(x, prec::Int) - setprecision(BigFloat, prec) do - BigFloat(x) - end -end - -""" - BigFloat(x, prec::Int, rounding::RoundingMode) - -Create a representation of `x` as a [`BigFloat`](@ref) with precision `prec` and -[`Rounding Mode`](@ref Base.Rounding.RoundingMode) `rounding`. -""" -function BigFloat(x, prec::Int, rounding::RoundingMode) - setrounding(BigFloat, rounding) do - BigFloat(x, prec) - end -end - -""" - BigFloat(x, rounding::RoundingMode) - -Create a representation of `x` as a [`BigFloat`](@ref) with the current global precision -and [`Rounding Mode`](@ref Base.Rounding.RoundingMode) `rounding`. -""" -function BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) - BigFloat(x, precision(BigFloat), rounding) -end +BigFloat(x::Real, r::RoundingMode; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(x, convert(MPFRRoundingMode, r); precision=precision) +BigFloat(x::AbstractString, r::RoundingMode; precision::Integer=DEFAULT_PRECISION[]) = + BigFloat(x, convert(MPFRRoundingMode, r); precision=precision) +## BigFloat -> Integer """ - BigFloat(x::String) + MPFR.unsafe_cast(T, x::BigFloat, r::RoundingMode) -Create a representation of the string `x` as a [`BigFloat`](@ref). +Convert `x` to integer type `T`, rounding the direction of `r`. If the value is not +representable by T, an arbitrary value will be returned. """ -BigFloat(x::AbstractString) = parse(BigFloat, x) +unsafe_cast(T, x::BigFloat, r::RoundingMode) = unsafe_cast(T, x, convert(MPFRRoundingMode, r)) - -## BigFloat -> Integer -function unsafe_cast(::Type{Int64}, x::BigFloat, ri::Cint) - ccall((:__gmpfr_mpfr_get_sj,:libmpfr), Cintmax_t, (Ref{BigFloat}, Cint), x, ri) +function unsafe_cast(::Type{Int64}, x::BigFloat, r::MPFRRoundingMode) + ccall((:__gmpfr_mpfr_get_sj,:libmpfr), Cintmax_t, (Ref{BigFloat}, MPFRRoundingMode), x, r) end -function unsafe_cast(::Type{UInt64}, x::BigFloat, ri::Cint) - ccall((:__gmpfr_mpfr_get_uj,:libmpfr), Cuintmax_t, (Ref{BigFloat}, Cint), x, ri) +function unsafe_cast(::Type{UInt64}, x::BigFloat, r::MPFRRoundingMode) + ccall((:__gmpfr_mpfr_get_uj,:libmpfr), Cuintmax_t, (Ref{BigFloat}, MPFRRoundingMode), x, r) end -function unsafe_cast(::Type{T}, x::BigFloat, ri::Cint) where T<:Signed - unsafe_cast(Int64, x, ri) % T +function unsafe_cast(::Type{T}, x::BigFloat, r::MPFRRoundingMode) where T<:Signed + unsafe_cast(Int64, x, r) % T end -function unsafe_cast(::Type{T}, x::BigFloat, ri::Cint) where T<:Unsigned - unsafe_cast(UInt64, x, ri) % T +function unsafe_cast(::Type{T}, x::BigFloat, r::MPFRRoundingMode) where T<:Unsigned + unsafe_cast(UInt64, x, r) % T end -function unsafe_cast(::Type{BigInt}, x::BigFloat, ri::Cint) +function unsafe_cast(::Type{BigInt}, x::BigFloat, r::MPFRRoundingMode) # actually safe, just keep naming consistent z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ref{BigInt}, Ref{BigFloat}, Int32), z, x, ri) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ref{BigInt}, Ref{BigFloat}, MPFRRoundingMode), z, x, r) return z end -unsafe_cast(::Type{Int128}, x::BigFloat, ri::Cint) = Int128(unsafe_cast(BigInt, x, ri)) -unsafe_cast(::Type{UInt128}, x::BigFloat, ri::Cint) = UInt128(unsafe_cast(BigInt, x, ri)) -unsafe_cast(::Type{T}, x::BigFloat, r::RoundingMode) where {T<:Integer} = unsafe_cast(T, x, to_mpfr(r)) +unsafe_cast(::Type{Int128}, x::BigFloat, r::MPFRRoundingMode) = Int128(unsafe_cast(BigInt, x, r)) +unsafe_cast(::Type{UInt128}, x::BigFloat, r::MPFRRoundingMode) = UInt128(unsafe_cast(BigInt, x, r)) unsafe_trunc(::Type{T}, x::BigFloat) where {T<:Integer} = unsafe_cast(T, x, RoundToZero) @@ -288,22 +326,18 @@ function (::Type{T})(x::BigFloat) where T<:Integer end ## BigFloat -> AbstractFloat - _cpynansgn(x::AbstractFloat, y::BigFloat) = isnan(x) && signbit(x) != signbit(y) ? -x : x -Float64(x::BigFloat) = - _cpynansgn(ccall((:mpfr_get_d,:libmpfr), Float64, (Ref{BigFloat}, Int32), x, ROUNDING_MODE[]), x) -Float32(x::BigFloat) = - _cpynansgn(ccall((:mpfr_get_flt,:libmpfr), Float32, (Ref{BigFloat}, Int32), x, ROUNDING_MODE[]), x) -# TODO: avoid double rounding -Float16(x::BigFloat) = Float16(Float32(x)) +Float64(x::BigFloat, r::MPFRRoundingMode=ROUNDING_MODE[]) = + _cpynansgn(ccall((:mpfr_get_d,:libmpfr), Float64, (Ref{BigFloat}, MPFRRoundingMode), x, r), x) +Float64(x::BigFloat, r::RoundingMode) = Float64(x, convert(MPFRRoundingMode, r)) + +Float32(x::BigFloat, r::MPFRRoundingMode=ROUNDING_MODE[]) = + _cpynansgn(ccall((:mpfr_get_flt,:libmpfr), Float32, (Ref{BigFloat}, MPFRRoundingMode), x, r), x) +Float32(x::BigFloat, r::RoundingMode) = Float32(x, convert(MPFRRoundingMode, r)) -Float64(x::BigFloat, r::RoundingMode) = - _cpynansgn(ccall((:mpfr_get_d,:libmpfr), Float64, (Ref{BigFloat}, Int32), x, to_mpfr(r)), x) -Float32(x::BigFloat, r::RoundingMode) = - _cpynansgn(ccall((:mpfr_get_flt,:libmpfr), Float32, (Ref{BigFloat}, Int32), x, to_mpfr(r)), x) # TODO: avoid double rounding -Float16(x::BigFloat, r::RoundingMode) = Float16(Float32(x, r)) +Float16(x::BigFloat) = Float16(Float32(x)) promote_rule(::Type{BigFloat}, ::Type{<:Real}) = BigFloat promote_rule(::Type{BigInt}, ::Type{<:AbstractFloat}) = BigFloat @@ -325,14 +359,14 @@ for (fJ, fC) in ((:+,:add), (:*,:mul)) # BigFloat function ($fJ)(x::BigFloat, y::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end # Unsigned Integer function ($fJ)(x::BigFloat, c::CulongMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_ui)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_ui)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end ($fJ)(c::CulongMax, x::BigFloat) = ($fJ)(x,c) @@ -340,7 +374,7 @@ for (fJ, fC) in ((:+,:add), (:*,:mul)) # Signed Integer function ($fJ)(x::BigFloat, c::ClongMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_si)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_si)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end ($fJ)(c::ClongMax, x::BigFloat) = ($fJ)(x,c) @@ -348,7 +382,7 @@ for (fJ, fC) in ((:+,:add), (:*,:mul)) # Float32/Float64 function ($fJ)(x::BigFloat, c::CdoubleMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_d)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_d)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end ($fJ)(c::CdoubleMax, x::BigFloat) = ($fJ)(x,c) @@ -356,7 +390,7 @@ for (fJ, fC) in ((:+,:add), (:*,:mul)) # BigInt function ($fJ)(x::BigFloat, c::BigInt) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_z)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_z)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end ($fJ)(c::BigInt, x::BigFloat) = ($fJ)(x,c) @@ -368,50 +402,50 @@ for (fJ, fC) in ((:-,:sub), (:/,:div)) # BigFloat function ($fJ)(x::BigFloat, y::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end # Unsigned Int function ($fJ)(x::BigFloat, c::CulongMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_ui)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_ui)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end function ($fJ)(c::CulongMax, x::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,:ui_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Culong, Ref{BigFloat}, Int32), z, c, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,:ui_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Culong, Ref{BigFloat}, MPFRRoundingMode), z, c, x, ROUNDING_MODE[]) return z end # Signed Integer function ($fJ)(x::BigFloat, c::ClongMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_si)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_si)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end function ($fJ)(c::ClongMax, x::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,:si_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Clong, Ref{BigFloat}, Int32), z, c, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,:si_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Clong, Ref{BigFloat}, MPFRRoundingMode), z, c, x, ROUNDING_MODE[]) return z end # Float32/Float64 function ($fJ)(x::BigFloat, c::CdoubleMax) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_d)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_d)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end function ($fJ)(c::CdoubleMax, x::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,:d_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Cdouble, Ref{BigFloat}, Int32), z, c, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,:d_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Cdouble, Ref{BigFloat}, MPFRRoundingMode), z, c, x, ROUNDING_MODE[]) return z end # BigInt function ($fJ)(x::BigFloat, c::BigInt) z = BigFloat() - ccall(($(string(:mpfr_,fC,:_z)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, Int32), z, x, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC,:_z)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, MPFRRoundingMode), z, x, c, ROUNDING_MODE[]) return z end # no :mpfr_z_div function @@ -420,7 +454,7 @@ end function -(c::BigInt, x::BigFloat) z = BigFloat() - ccall((:mpfr_z_sub, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigInt}, Ref{BigFloat}, Int32), z, c, x, ROUNDING_MODE[]) + ccall((:mpfr_z_sub, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigInt}, Ref{BigFloat}, MPFRRoundingMode), z, c, x, ROUNDING_MODE[]) return z end @@ -428,7 +462,7 @@ inv(x::BigFloat) = one(Clong) / x # faster than fallback one(x)/x function fma(x::BigFloat, y::BigFloat, z::BigFloat) r = BigFloat() - ccall(("mpfr_fma",:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), r, x, y, z, ROUNDING_MODE[]) + ccall(("mpfr_fma",:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), r, x, y, z, ROUNDING_MODE[]) return r end @@ -436,7 +470,7 @@ end # BigFloat function div(x::BigFloat, y::BigFloat) z = BigFloat() - ccall((:mpfr_div,:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, to_mpfr(RoundToZero)) + ccall((:mpfr_div,:libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end @@ -444,13 +478,13 @@ end # Unsigned Int function div(x::BigFloat, c::CulongMax) z = BigFloat() - ccall((:mpfr_div_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), z, x, c, to_mpfr(RoundToZero)) + ccall((:mpfr_div_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode), z, x, c, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end function div(c::CulongMax, x::BigFloat) z = BigFloat() - ccall((:mpfr_ui_div, :libmpfr), Int32, (Ref{BigFloat}, Culong, Ref{BigFloat}, Int32), z, c, x, to_mpfr(RoundToZero)) + ccall((:mpfr_ui_div, :libmpfr), Int32, (Ref{BigFloat}, Culong, Ref{BigFloat}, MPFRRoundingMode), z, c, x, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end @@ -458,13 +492,13 @@ end # Signed Integer function div(x::BigFloat, c::ClongMax) z = BigFloat() - ccall((:mpfr_div_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, x, c, to_mpfr(RoundToZero)) + ccall((:mpfr_div_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, x, c, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end function div(c::ClongMax, x::BigFloat) z = BigFloat() - ccall((:mpfr_si_div, :libmpfr), Int32, (Ref{BigFloat}, Clong, Ref{BigFloat}, Int32), z, c, x, to_mpfr(RoundToZero)) + ccall((:mpfr_si_div, :libmpfr), Int32, (Ref{BigFloat}, Clong, Ref{BigFloat}, MPFRRoundingMode), z, c, x, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end @@ -472,13 +506,13 @@ end # Float32/Float64 function div(x::BigFloat, c::CdoubleMax) z = BigFloat() - ccall((:mpfr_div_d, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, Int32), z, x, c, to_mpfr(RoundToZero)) + ccall((:mpfr_div_d, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Cdouble, MPFRRoundingMode), z, x, c, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end function div(c::CdoubleMax, x::BigFloat) z = BigFloat() - ccall((:mpfr_d_div, :libmpfr), Int32, (Ref{BigFloat}, Cdouble, Ref{BigFloat}, Int32), z, c, x, to_mpfr(RoundToZero)) + ccall((:mpfr_d_div, :libmpfr), Int32, (Ref{BigFloat}, Cdouble, Ref{BigFloat}, MPFRRoundingMode), z, c, x, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end @@ -486,7 +520,7 @@ end # BigInt function div(x::BigFloat, c::BigInt) z = BigFloat() - ccall((:mpfr_div_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, Int32), z, x, c, to_mpfr(RoundToZero)) + ccall((:mpfr_div_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, MPFRRoundingMode), z, x, c, RoundToZero) ccall((:mpfr_trunc, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}), z, z) return z end @@ -497,23 +531,23 @@ for (fJ, fC, fI) in ((:+, :add, 0), (:*, :mul, 1)) @eval begin function ($fJ)(a::BigFloat, b::BigFloat, c::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, a, b, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, a, b, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, c, ROUNDING_MODE[]) return z end function ($fJ)(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, a, b, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, c, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, d, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, a, b, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, d, ROUNDING_MODE[]) return z end function ($fJ)(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat, e::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, a, b, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, c, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, d, ROUNDING_MODE[]) - ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, z, e, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, a, b, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, c, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, d, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,fC)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, e, ROUNDING_MODE[]) return z end end @@ -521,14 +555,14 @@ end function -(x::BigFloat) z = BigFloat() - ccall((:mpfr_neg, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall((:mpfr_neg, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) return z end function sqrt(x::BigFloat) isnan(x) && return x z = BigFloat() - ccall((:mpfr_sqrt, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall((:mpfr_sqrt, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) isnan(z) && throw(DomainError(x, "NaN result for non-NaN input.")) return z end @@ -537,25 +571,25 @@ sqrt(x::BigInt) = sqrt(BigFloat(x)) function ^(x::BigFloat, y::BigFloat) z = BigFloat() - ccall((:mpfr_pow, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_pow, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end function ^(x::BigFloat, y::CulongMax) z = BigFloat() - ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end function ^(x::BigFloat, y::ClongMax) z = BigFloat() - ccall((:mpfr_pow_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end function ^(x::BigFloat, y::BigInt) z = BigFloat() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigInt}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -565,7 +599,7 @@ end for f in (:exp, :exp2, :exp10, :expm1, :cosh, :sinh, :tanh, :sech, :csch, :coth, :cbrt) @eval function $f(x::BigFloat) z = BigFloat() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) return z end end @@ -573,7 +607,7 @@ end function sincos_fast(v::BigFloat) s = BigFloat() c = BigFloat() - ccall((:mpfr_sin_cos, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), s, c, v, ROUNDING_MODE[]) + ccall((:mpfr_sin_cos, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), s, c, v, ROUNDING_MODE[]) return (s, c) end sincos(v::BigFloat) = sincos_fast(v) @@ -581,18 +615,18 @@ sincos(v::BigFloat) = sincos_fast(v) # return log(2) function big_ln2() c = BigFloat() - ccall((:mpfr_const_log2, :libmpfr), Cint, (Ref{BigFloat}, Int32), c, MPFR.ROUNDING_MODE[]) + ccall((:mpfr_const_log2, :libmpfr), Cint, (Ref{BigFloat}, MPFRRoundingMode), c, MPFR.ROUNDING_MODE[]) return c end function ldexp(x::BigFloat, n::Clong) z = BigFloat() - ccall((:mpfr_mul_2si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, x, n, ROUNDING_MODE[]) + ccall((:mpfr_mul_2si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, x, n, ROUNDING_MODE[]) return z end function ldexp(x::BigFloat, n::Culong) z = BigFloat() - ccall((:mpfr_mul_2ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), z, x, n, ROUNDING_MODE[]) + ccall((:mpfr_mul_2ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, MPFRRoundingMode), z, x, n, ROUNDING_MODE[]) return z end ldexp(x::BigFloat, n::ClongMax) = ldexp(x, convert(Clong, n)) @@ -605,13 +639,13 @@ function factorial(x::BigFloat) end ui = convert(Culong, x) z = BigFloat() - ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ref{BigFloat}, Culong, Int32), z, ui, ROUNDING_MODE[]) + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ref{BigFloat}, Culong, MPFRRoundingMode), z, ui, ROUNDING_MODE[]) return z end function hypot(x::BigFloat, y::BigFloat) z = BigFloat() - ccall((:mpfr_hypot, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_hypot, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -622,7 +656,7 @@ for f in (:log, :log2, :log10) "with a complex argument. Try ", $f, "(complex(x))."))) end z = BigFloat() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) return z end end @@ -633,7 +667,7 @@ function log1p(x::BigFloat) "with a complex argument. Try log1p(complex(x))."))) end z = BigFloat() - ccall((:mpfr_log1p, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall((:mpfr_log1p, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) return z end @@ -641,7 +675,7 @@ function max(x::BigFloat, y::BigFloat) isnan(x) && return x isnan(y) && return y z = BigFloat() - ccall((:mpfr_max, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_max, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -649,7 +683,7 @@ function min(x::BigFloat, y::BigFloat) isnan(x) && return x isnan(y) && return y z = BigFloat() - ccall((:mpfr_min, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_min, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -657,19 +691,19 @@ function modf(x::BigFloat) isinf(x) && return (BigFloat(NaN), x) zint = BigFloat() zfloat = BigFloat() - ccall((:mpfr_modf, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), zint, zfloat, x, ROUNDING_MODE[]) + ccall((:mpfr_modf, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), zint, zfloat, x, ROUNDING_MODE[]) return (zfloat, zint) end function rem(x::BigFloat, y::BigFloat) z = BigFloat() - ccall((:mpfr_fmod, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_fmod, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end function rem(x::BigFloat, y::BigFloat, ::RoundingMode{:Nearest}) z = BigFloat() - ccall((:mpfr_remainder, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_remainder, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -680,7 +714,7 @@ function sum(arr::AbstractArray{BigFloat}) z = BigFloat(0) for i in arr ccall((:mpfr_add, :libmpfr), Int32, - (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Cint), z, z, i, 0) + (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, z, i, ROUNDING_MODE[]) end return z end @@ -691,7 +725,7 @@ for f in (:sin, :cos, :tan, :sec, :csc, :acos, :asin, :atan, :acosh, :asinh, :at function ($f)(x::BigFloat) isnan(x) && return x z = BigFloat() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, ROUNDING_MODE[]) + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) isnan(z) && throw(DomainError(x, "NaN result for non-NaN input.")) return z end @@ -700,7 +734,7 @@ end function atan(y::BigFloat, x::BigFloat) z = BigFloat() - ccall((:mpfr_atan2, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, y, x, ROUNDING_MODE[]) + ccall((:mpfr_atan2, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, y, x, ROUNDING_MODE[]) return z end @@ -759,14 +793,14 @@ end Get the precision (in bits) currently used for [`BigFloat`](@ref) arithmetic. """ -precision(::Type{BigFloat}) = DEFAULT_PRECISION[] # precision of the type BigFloat itself +precision(::Type{BigFloat}) = Int(DEFAULT_PRECISION[]) # precision of the type BigFloat itself """ setprecision([T=BigFloat,] precision::Int) Set the precision (in bits) to be used for `T` arithmetic. """ -function setprecision(::Type{BigFloat}, precision::Int) +function setprecision(::Type{BigFloat}, precision::Integer) if precision < 2 throw(DomainError(precision, "`precision` cannot be less than 2.")) end @@ -774,43 +808,14 @@ function setprecision(::Type{BigFloat}, precision::Int) return precision end -setprecision(precision::Int) = setprecision(BigFloat, precision) +setprecision(precision::Integer) = setprecision(BigFloat, precision) maxintfloat(x::BigFloat) = BigFloat(2)^precision(x) maxintfloat(::Type{BigFloat}) = BigFloat(2)^precision(BigFloat) -to_mpfr(::RoundingMode{:Nearest}) = Cint(0) -to_mpfr(::RoundingMode{:ToZero}) = Cint(1) -to_mpfr(::RoundingMode{:Up}) = Cint(2) -to_mpfr(::RoundingMode{:Down}) = Cint(3) -to_mpfr(::RoundingMode{:FromZero}) = Cint(4) - -function from_mpfr(c::Integer) - if c == 0 - return RoundNearest - elseif c == 1 - return RoundToZero - elseif c == 2 - return RoundUp - elseif c == 3 - return RoundDown - elseif c == 4 - return RoundFromZero - else - throw(ArgumentError("invalid MPFR rounding mode code: $c")) - end - RoundingMode(c) -end - -rounding_raw(::Type{BigFloat}) = ROUNDING_MODE[] -setrounding_raw(::Type{BigFloat},i::Integer) = ROUNDING_MODE[] = i - -rounding(::Type{BigFloat}) = from_mpfr(rounding_raw(BigFloat)) -setrounding(::Type{BigFloat},r::RoundingMode) = setrounding_raw(BigFloat,to_mpfr(r)) - function copysign(x::BigFloat, y::BigFloat) z = BigFloat() - ccall((:mpfr_copysign, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, Int32), z, x, y, ROUNDING_MODE[]) + ccall((:mpfr_copysign, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, y, ROUNDING_MODE[]) return z end @@ -825,16 +830,16 @@ end function frexp(x::BigFloat) z = BigFloat() c = Ref{Clong}() - ccall((:mpfr_frexp, :libmpfr), Int32, (Ptr{Clong}, Ref{BigFloat}, Ref{BigFloat}, Cint), c, z, x, ROUNDING_MODE[]) + ccall((:mpfr_frexp, :libmpfr), Int32, (Ptr{Clong}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), c, z, x, ROUNDING_MODE[]) return (z, c[]) end function significand(x::BigFloat) z = BigFloat() c = Ref{Clong}() - ccall((:mpfr_frexp, :libmpfr), Int32, (Ptr{Clong}, Ref{BigFloat}, Ref{BigFloat}, Cint), c, z, x, ROUNDING_MODE[]) + ccall((:mpfr_frexp, :libmpfr), Int32, (Ptr{Clong}, Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), c, z, x, ROUNDING_MODE[]) # Double the significand to make it work as Base.significand - ccall((:mpfr_mul_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, Int32), z, z, 2, ROUNDING_MODE[]) + ccall((:mpfr_mul_si, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Clong, MPFRRoundingMode), z, z, 2, ROUNDING_MODE[]) return z end @@ -874,7 +879,7 @@ isone(x::BigFloat) = x == Clong(1) function nextfloat(x::BigFloat) z = BigFloat() - ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), + ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) ccall((:mpfr_nextabove, :libmpfr), Int32, (Ref{BigFloat},), z) != 0 return z @@ -882,7 +887,7 @@ end function prevfloat(x::BigFloat) z = BigFloat() - ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), + ccall((:mpfr_set, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, MPFRRoundingMode), z, x, ROUNDING_MODE[]) ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ref{BigFloat},), z) != 0 return z @@ -916,7 +921,7 @@ function setprecision(f::Function, ::Type{T}, prec::Integer) where T end end -setprecision(f::Function, precision::Integer) = setprecision(f, BigFloat, precision) +setprecision(f::Function, prec::Integer) = setprecision(f, BigFloat, prec) function string_mpfr(x::BigFloat, fmt::String) buf = Base.StringVector(0) diff --git a/base/parse.jl b/base/parse.jl index 202390278e9f5a..c0edba65879517 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -350,8 +350,8 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: end return result end -function tryparse_internal(::Type{T}, s::AbstractString, raise::Bool) where T<:Real - result = tryparse(T, s) +function tryparse_internal(::Type{T}, s::AbstractString, raise::Bool; kwargs...) where T<:Real + result = tryparse(T, s; kwargs...) if raise && result === nothing _parse_failure(T, s) end @@ -363,8 +363,8 @@ end tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int, raise::Bool) where T<:Integer = tryparse_internal(T, s, startpos, endpos, 10, raise) -parse(::Type{T}, s::AbstractString) where T<:Real = - convert(T, tryparse_internal(T, s, true)) +parse(::Type{T}, s::AbstractString; kwargs...) where T<:Real = + convert(T, tryparse_internal(T, s, true; kwargs...)) parse(::Type{T}, s::AbstractString) where T<:Complex = convert(T, tryparse_internal(T, s, firstindex(s), lastindex(s), true)) diff --git a/base/sysimg.jl b/base/sysimg.jl index 84c2f471639d39..5c3917ce1e5f7f 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -362,6 +362,10 @@ using .FastMath function deepcopy_internal end +# enums +include("Enums.jl") +using .Enums + # BigInts and BigFloats include("gmp.jl") using .GMP @@ -394,10 +398,6 @@ include("printf.jl") # metaprogramming include("meta.jl") -# enums -include("Enums.jl") -using .Enums - # concurrency and parallelism include("channels.jl") diff --git a/doc/src/base/numbers.md b/doc/src/base/numbers.md index 50e6d2b7134da6..f07f7f586d8261 100644 --- a/doc/src/base/numbers.md +++ b/doc/src/base/numbers.md @@ -120,13 +120,10 @@ and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] (https://gmplib.org) is used. ```@docs -Base.MPFR.BigFloat(::Any) +Base.MPFR.BigFloat(::Any, rounding::RoundingMode) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision -Base.MPFR.BigFloat(x, prec::Int) -Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) -Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index 7ec0c3930eb329..7451de367e89be 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -81,7 +81,7 @@ function _rand(rng::AbstractRNG, sp::SamplerBigFloat, ::CloseOpen01{BigFloat}) z.exp = 0 randbool && ccall((:mpfr_sub_d, :libmpfr), Int32, - (Ref{BigFloat}, Ref{BigFloat}, Cdouble, Int32), + (Ref{BigFloat}, Ref{BigFloat}, Cdouble, Base.MPFR.MPFRRoundingMode), z, z, 0.5, Base.MPFR.ROUNDING_MODE[]) z end @@ -90,7 +90,7 @@ end # TODO: make an API for requesting full or not-full precision function _rand(rng::AbstractRNG, sp::SamplerBigFloat, ::CloseOpen01{BigFloat}, ::Nothing) z = _rand(rng, sp, CloseOpen12(BigFloat)) - ccall((:mpfr_sub_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Int32), + ccall((:mpfr_sub_ui, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Culong, Base.MPFR.MPFRRoundingMode), z, z, 1, Base.MPFR.ROUNDING_MODE[]) z end diff --git a/test/mpfr.jl b/test/mpfr.jl index 3e69762caf081d..9c3a2bde4847ef 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -45,7 +45,7 @@ import Base.MPFR @test precision(xs[end]) != prec for x in xs @test precision(BigFloat(x)) == prec - @test precision(BigFloat(x, prec ÷ 2)) == prec ÷ 2 + @test precision(BigFloat(x; precision=prec ÷ 2)) == prec ÷ 2 end end end