Working on double-double math, I found this to be a problem. It makes validating high precision numerics more difficult than it should be. The example illustrates what is going on.
#= parse(Float64,string(BigFloat)) is less accurate than it should be at least in this case BigFloat is the result of BigFloat addition =# Base.ldexp(signif::Integer, pow2::Integer) = ldexp(signif+zero(Float64), pow2); set_bigfloat_precision(ceil(Int,112*log(10)/log(2))); piStr = string( "3.141592653589793238462643383279502884197169399375105820", "9749445923078164062862089986280348253421170679821480865132" ); piBig = parse(BigFloat,piStr); piStr == string(piBig) # true # the double-double value nearest Pi nearpi_qhi = 884279719003555//281474976710656; nearpi_qlo = 4967757600021511//40564819207303340847894502572032; nearpi_hi = ldexp(num(nearpi_qhi),-round(Int,log2(den(nearpi_qhi)))); nearpi_lo = ldexp(num(nearpi_qlo),-round(Int,log2(den(nearpi_qlo)))); nearpi_q = nearpi_qhi + nearpi_qlo; nearpi_num = num(nearpi_q); nearpi_pow2 = -round(Int,log2(den(nearpi_q))); ldexp(nearpi_num,nearpi_pow2) == nearpi_hi # true nearpiBig = ldexp(parse(BigFloat,string(nearpi_num)),nearpi_pow2); # 3.14159265358979..187500000000 abserr=abs(piBig-nearpiBig); relerr=abserr/piBig; abserr, relerr # ~(2.995-33,9.533-34) # replacing nearpi_lo with nextfloat(_) or prevfloat(_) # makes the abserr and relerr values more coarse # ∴ these values are the best Float64x2 approximation parse_recover_nearpi = parse(BigFloat,string(nearpi_hi)) + parse(BigFloat,string(nearpi_lo)); coerce_recover_nearpi = BigFloat(nearpi_hi) + BigFloat(nearpi_lo); parse_recover_nearpi == nearpiBig # false coerce_recover_nearpi == nearpiBig # true #= numerical interconversion antisymmetry is unhelpful --------------------------------------------------- better value obtains with parse(BigFloat,string(Float64)) better value obtains with Float64(value(BigFloat)) and not with parse(Float64,string(BigFloat)) =#