crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Using MPFR for `BigFloat`

Open HertzDevil opened this issue 2 years ago • 1 comments

The MPFR library addresses several deficiencies in the mpf_* functions provided by GMP:

  • It has proper IEEE 754 semantics, e.g. infinity and accurate rounding;
  • It provides definitions for almost all of the mathematical functions we define in Math, like sin and the floating-point manipulation functions;
  • MPFR floats support arbitrary-precision string conversions (see https://github.com/crystal-lang/crystal/pull/10632#issuecomment-885418088).

So I think we should use that on top of GMP (we cannot replace it because GMP as a whole also provides BigInt and BigRational). MPFR provides functions to convert to and from GMP's mpf_t in case any Crystal code depends on LibGMP::MPF directly.

HertzDevil avatar Nov 07 '21 09:11 HertzDevil

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 equivalent
  • MPFR_RNDF, faithful rounding, only supported for a subset of operations, has no Crystal equivalent
  • MPFR_RNDNA, internal use only, equivalent to RoundingMode::TIES_EVEN
    • the public macro mpfr_round_nearest_away emulates this, and fortunately can be ported to Crystal

Those 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.

HertzDevil avatar Aug 17 '22 18:08 HertzDevil