diff --git a/base/mpfr.jl b/base/mpfr.jl index 8f12968c4a701..289f43a0bebd5 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -66,14 +66,16 @@ type BigFloat <: AbstractFloat sign::Cint exp::Clong d::Ptr{Limb} + function BigFloat() - N = precision(BigFloat) + prec = precision(BigFloat) z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL) - ccall((:mpfr_init2,:libmpfr), Void, (Ptr{BigFloat}, Clong), &z, N) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{BigFloat}, Clong), &z, prec) finalizer(z, cglobal((:mpfr_clear, :libmpfr))) return z end - # Not recommended for general use + + # Not recommended for general use: function BigFloat(prec::Clong, sign::Cint, exp::Clong, d::Ptr{Void}) new(prec, sign, exp, d) end @@ -118,6 +120,46 @@ end convert(::Type{Rational}, x::BigFloat) = convert(Rational{BigInt}, x) convert(::Type{AbstractFloat}, x::BigInt) = BigFloat(x) +# generic constructor with arbitrary precision: +""" + BigFloat(x, prec::Int) + +Create a representation of `x` as a `BigFloat` 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` with precision `prec` and rounding mode `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` with the current global precision and rounding mode `rounding`. +""" +function BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) + BigFloat(x, precision(BigFloat), rounding) +end + +""" + BigFloat(x::String) + +Create a representation of the string `x` as a `BigFloat`. +""" +BigFloat(x::String) = parse(BigFloat, x) + + ## BigFloat -> Integer function unsafe_cast(::Type{Int64}, x::BigFloat, ri::Cint) ccall((:__gmpfr_mpfr_get_sj,:libmpfr), Cintmax_t, diff --git a/doc/src/stdlib/numbers.md b/doc/src/stdlib/numbers.md index 908bf2b236701..715a8319f9b18 100644 --- a/doc/src/stdlib/numbers.md +++ b/doc/src/stdlib/numbers.md @@ -102,11 +102,20 @@ The `BigFloat` type implements arbitrary-precision floating-point arithmetic usi ```@docs Base.precision +Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision ``` +### Additional constructors for `BigFloat` +```@docs +Base.MPFR.BigFloat(x, prec::Int) +BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) +Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) +Base.MPFR.BigFloat(x::String) +``` ## Random Numbers + Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple diff --git a/test/mpfr.jl b/test/mpfr.jl index cbef129d71a6e..2660e151cf218 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -873,3 +873,26 @@ let b = IOBuffer() end @test isnan(sqrt(BigFloat(NaN))) + +# PR 17217 -- BigFloat constructors with given precision and rounding mode + +# test constructors and `big` with additional precision and rounding mode: + +for prec in (10, 100, 1000) + for val in ("3.1", pi, "-1.3", 3.1) + let + a = BigFloat(val) + b = BigFloat(val, prec) + c = BigFloat(val, RoundUp) + d = BigFloat(val, prec, RoundDown) + e = BigFloat(val, prec, RoundUp) + + @test precision(a) == precision(BigFloat) + @test precision(b) == prec + @test precision(c) == precision(BigFloat) + @test precision(d) == prec + @test precision(e) == prec + (val != 3.1) && @test e > d # rounding has no effect when constructing from Float64 + end + end +end