Open HertzDevil opened 2 years ago
I was thinking about how to bridge the differences between our rounding modes and MPFR's. MPFR defines seven:
MPFR_RNDN
, equivalent to RoundingMode::TIES_EVEN
MPFR_RNDZ
, equivalent to RoundingMode::TO_ZERO
MPFR_RNDU
, equivalent to RoundingMode::TO_POSITIVE
MPFR_RNDD
, equivalent to RoundingMode::TO_NEGATIVE
MPFR_RNDA
, round away from zero, has no Crystal equivalentMPFR_RNDF
, faithful rounding, only supported for a subset of operations, has no Crystal equivalentMPFR_RNDNA
, internal use only, equivalent to RoundingMode::TIES_EVEN
mpfr_round_nearest_away
emulates this, and fortunately can be ported to CrystalThose rounding modes are available in almost every operation, where rounding occurs in the least significant bits in the mantissa, not just mpfr_round
(round to integer). There is also a default rounding mode configurable by mpfr_set_default_rounding_mode
, but it doesn't appear to be used by MPFR itself, and is only for the GMP MPF compatibility mode shown here. Thus it would make no sense to bind that function here, because adding MPFR to the standard library implies not using LibGMP::MPF
at all.
I don't think the standard library would enjoy supplying a rounding mode parameter to every method on BigFloat
. So outside of the few rounding-related methods, MPFR_RNDN
should be passed to MPFR. #11097 might mean that we could roll our own default mode.
One particular benefit is it provides mpfr_frexp
which avoids an overflow in our current implementation of Math.frexp(BigFloat)
:
LibGMP.mpf_get_d_2exp(out exp, 2.to_big_f ** (UInt64::MAX // 2))
Errno.value # => Errno::EINVAL
exp # => -9223372036854775808
The MPFR library addresses several deficiencies in the
mpf_*
functions provided by GMP:Math
, likesin
and the floating-point manipulation functions;So I think we should use that on top of GMP (we cannot replace it because GMP as a whole also provides
BigInt
andBigRational
). MPFR provides functions to convert to and from GMP'smpf_t
in case any Crystal code depends onLibGMP::MPF
directly.