Skip to content

Commit c5c417c

Browse files
dpsandersStefanKarpinski
authored andcommitted
BigFloat constructors with given precision and/or rounding mode (#17217)
1 parent 6ce0102 commit c5c417c

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

base/mpfr.jl

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,16 @@ type BigFloat <: AbstractFloat
6666
sign::Cint
6767
exp::Clong
6868
d::Ptr{Limb}
69+
6970
function BigFloat()
70-
N = precision(BigFloat)
71+
prec = precision(BigFloat)
7172
z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL)
72-
ccall((:mpfr_init2,:libmpfr), Void, (Ptr{BigFloat}, Clong), &z, N)
73+
ccall((:mpfr_init2,:libmpfr), Void, (Ptr{BigFloat}, Clong), &z, prec)
7374
finalizer(z, cglobal((:mpfr_clear, :libmpfr)))
7475
return z
7576
end
76-
# Not recommended for general use
77+
78+
# Not recommended for general use:
7779
function BigFloat(prec::Clong, sign::Cint, exp::Clong, d::Ptr{Void})
7880
new(prec, sign, exp, d)
7981
end
@@ -118,6 +120,46 @@ end
118120
convert(::Type{Rational}, x::BigFloat) = convert(Rational{BigInt}, x)
119121
convert(::Type{AbstractFloat}, x::BigInt) = BigFloat(x)
120122

123+
# generic constructor with arbitrary precision:
124+
"""
125+
BigFloat(x, prec::Int)
126+
127+
Create a representation of `x` as a `BigFloat` with precision `prec`.
128+
"""
129+
function BigFloat(x, prec::Int)
130+
setprecision(BigFloat, prec) do
131+
BigFloat(x)
132+
end
133+
end
134+
135+
"""
136+
BigFloat(x, prec::Int, rounding::RoundingMode)
137+
138+
Create a representation of `x` as a `BigFloat` with precision `prec` and rounding mode `rounding`.
139+
"""
140+
function BigFloat(x, prec::Int, rounding::RoundingMode)
141+
setrounding(BigFloat, rounding) do
142+
BigFloat(x, prec)
143+
end
144+
end
145+
146+
"""
147+
BigFloat(x, rounding::RoundingMode)
148+
149+
Create a representation of `x` as a `BigFloat` with the current global precision and rounding mode `rounding`.
150+
"""
151+
function BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode)
152+
BigFloat(x, precision(BigFloat), rounding)
153+
end
154+
155+
"""
156+
BigFloat(x::String)
157+
158+
Create a representation of the string `x` as a `BigFloat`.
159+
"""
160+
BigFloat(x::String) = parse(BigFloat, x)
161+
162+
121163
## BigFloat -> Integer
122164
function unsafe_cast(::Type{Int64}, x::BigFloat, ri::Cint)
123165
ccall((:__gmpfr_mpfr_get_sj,:libmpfr), Cintmax_t,

doc/src/stdlib/numbers.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,20 @@ The `BigFloat` type implements arbitrary-precision floating-point arithmetic usi
102102

103103
```@docs
104104
Base.precision
105+
Base.MPFR.precision(::Type{BigFloat})
105106
Base.MPFR.setprecision
106107
```
107108

109+
### Additional constructors for `BigFloat`
110+
```@docs
111+
Base.MPFR.BigFloat(x, prec::Int)
112+
BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode)
113+
Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode)
114+
Base.MPFR.BigFloat(x::String)
115+
```
108116
## Random Numbers
109117

118+
110119
Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT)
111120
via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types
112121
can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple

test/mpfr.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,3 +873,26 @@ let b = IOBuffer()
873873
end
874874

875875
@test isnan(sqrt(BigFloat(NaN)))
876+
877+
# PR 17217 -- BigFloat constructors with given precision and rounding mode
878+
879+
# test constructors and `big` with additional precision and rounding mode:
880+
881+
for prec in (10, 100, 1000)
882+
for val in ("3.1", pi, "-1.3", 3.1)
883+
let
884+
a = BigFloat(val)
885+
b = BigFloat(val, prec)
886+
c = BigFloat(val, RoundUp)
887+
d = BigFloat(val, prec, RoundDown)
888+
e = BigFloat(val, prec, RoundUp)
889+
890+
@test precision(a) == precision(BigFloat)
891+
@test precision(b) == prec
892+
@test precision(c) == precision(BigFloat)
893+
@test precision(d) == prec
894+
@test precision(e) == prec
895+
(val != 3.1) && @test e > d # rounding has no effect when constructing from Float64
896+
end
897+
end
898+
end

0 commit comments

Comments
 (0)