mpz_limbs interface

Niels Möller nisse at lysator.liu.se
Mon Feb 3 10:34:34 UTC 2014


Torbjorn Granlund <tg at gmplib.org> writes:

> nisse at lysator.liu.se (Niels Möller) writes:
>
>   This assumes that C++ allows initializers with arbitrary non-constant
>   expressions (does it?), and that we implement mpn_set_d.
>
> The top-level file extract-dbl.c kind-of does that already.

I'm not sure I understand what __gmp_extract_double is supposed to do.
In particular, how to interpret the return value.

For mpn_set_d, I think it would make some sense to have it return a
base-2 exponent, and write the mantissa to a few limbs. Number of limbs
would be a constant, part of the ABI, similar to LIMBS_PER_DOUBLE but
renamed for external use.

  mp_bitcnt_t 
  mpn_set_d (mp_limb_t rp[LIMBS_PER_BOUBLE], d);

defined so that after

  exp = mpn_set_d (rp, d);

one would have 

  |d| == {rp, LIMBS_PER_DOUBLE} * 2^exp

There should be no rounding (except possibly for obscure systems with
base-10 floats rather than base 2). This spec allows several valid
return values, and we can leave unspecified precisely which
representation is returned.

Or maybe we should specify that rp[LIMBS_PER_DOUBLE - 1] != 0 (and
handle d == 0 as a special case somehow).

And mpz_set_d could then be implemented like

void
mpz_set_d (mpz_ptr r, double d)
{
  int negative;
  mp_ptr rp;
  mp_size_t rn;
  mp_bitcnt_t exp;

  negative = d < 0;

  rn = LIMBS_PER_DOUBLE;
  rp = MPZ_REALLOC (r, rn);
  exp = mpn_set_d (rp, d);
  MPN_NORMALIZE (rp, rn);  /* Could skipped if mpz_set_d always normalize */

  SIZ(r) = negative ? -rn : rn;

  if (exp < 0)
    /* Not sure if we want tdiv or fdiv here? */
    mpz_tdiv_q_2exp (r, r, -exp);
  else if (exp > 0)
    mpz_mul_2exp (r, r, exp);
}

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list