Hi all
I’m a bit confused on the rules of precision “promotion” using BigFloats. As far as I can see, there are none. See example below. From this, I can conclude that
- Type promotion is made (the result of an operation with
Float64
andBigFloat
returns aBigFloat
) - Precision is not set based on the arguments of an operation, i.e. the result of an operation does not get a promoted/demoted precision. I was a bit surprised to see examples
e
andf
below. I would have expected to see the precision ofe
andf
to be 512 bits, not the default 256. - Precision of an operation is always set to 256 bits (the default for a
BigFloat
) unless the operation is made in a context with modified precision usingsetprecision()
.
Is this correct?
When computing with BigFloats having different precisions, how is this handled “internally”? Are these variables passed on to MPFR straight away and MPFR does the arithmetic? Or are they rounded down/up to the contextual precision first (creating intermediates)?
Any insights are more than welcome.
My context: I’m writing code that should handle a mix of Float64 and BigFloats (with different precisions) and the user should be able to specify the precision in which numerical operations are done and the precision in which the result is returned (can be different from the precision in which the operations are done). So if someone has a template for such a thing, feel free to share…
(v1.8) julia> a = 1.0
1.0
(v1.8) julia> typeof(a), precision(a)
(Float64, 53)
(v1.8) julia> b = BigFloat("3.14", 128)
3.14
(v1.8) julia> typeof(b), precision(b)
(BigFloat, 128)
(v1.8) julia> c = a + b
4.140000000000000000000000000000000000000470197740328915003187494614888898271127
(v1.8) julia> typeof(c), precision(c)
(BigFloat, 256)
(v1.8) julia> d = BigFloat("3.14", 512)
3.13999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999989
(v1.8) julia> typeof(d), precision(d)
(BigFloat, 512)
(v1.8) julia> e = a+d
4.140000000000000000000000000000000000000000000000000000000000000000000000000008
(v1.8) julia> typeof(e), precision(e)
(BigFloat, 256)
(v1.8) julia> f = b+d
6.280000000000000000000000000000000000000470197740328915003187494614888898271136
(v1.8) julia> typeof(f), precision(f)
(BigFloat, 256)
(v1.8) julia> g = BigFloat("0.0", 1024)
0.0
(v1.8) julia> typeof(g),precision(g)
(BigFloat, 1024)
(v1.8) julia> g += a
1.0
(v1.8) julia> typeof(g),precision(g)
(BigFloat, 256)
(v1.8) julia> h = BigFloat("0.0", 1024)
0.0
(v1.8) julia> h += d
3.140000000000000000000000000000000000000000000000000000000000000000000000000008
(v1.8) julia> typeof(h),precision(h)
(BigFloat, 256)
(v1.8) julia> i = BigFloat("0.0", 1024)
0.0
(v1.8) julia> typeof(i),precision(i)
(BigFloat, 1024)
(v1.8) julia> setprecision(512) do
j = a+i
typeof(j), precision(j)
end
(BigFloat, 512)