Karim Belabas on Wed, 05 Dec 2007 00:21:23 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Can PARI use GNU MP integers and rationals?


* Himanshu Jain [2007-12-04 23:13]:
> Hi everybody,
>
> I am new to PARI/GP. The problem I am working
> on contains numbers in GNU MP format. I need to use
> the PARI library as well.
>
> Is there some way of converting  GNU MP types mpz_t,
> mpq_t to t_INT, t_FRAC using PARI library
> routines.
>
> Some solutions I have in mind: first convert mpz_t to usual C
> type say signed long  and then convert that to t_INT. This may not
> always work if the original mpz_t is large. Another idea is to convert
> mpz_t to char* and then use gp_read_stream to obtain a GEN type.

( gp_read_str )

> Are there better solutions?

Using GMP's documented interface, I don't think so.

Glancing at the contents of /usr/include/gmp.h, something like the following
should work in practice [ completely untested code follows ] :

#define LIMBS(x)  ((mp_limb_t *)((x)+2))
#define NLIMBS(x) (lgefint(x)-2)
void
GEN2mpz(mpz_t X, GEN x)
{
  long l = NLIMBS(x);
  X->_mp_alloc = l;
  X->_mp_size = signe(x) > 0? l: -l;
  X->_mp_d = LIMBS(x); /* shallow! */
}
GEN
mpz2GEN(mpz_t X)
{
  long l = X->_mp_size, lx = labs(l)+2;
  GEN x = cgeti(lx)
  x[1] = evalsigne(l > 0? 1: -1) | evallgefint(lx);
  for (i = 2; i < lx; i++) x[i] = X->_mp_d[i-2];
}

Possibly after fixing the above (so that it compiles and runs as
intended), implementing mpq2GEN and GEN2mpq should be easy, e.g.

GEN
mpq2GEN(mpq_t Q) { return gdiv(mpz2GEN(Q->_mpnum), mpz2GEN(Q->_mp_den)); }

or (cleaner)

GEN
mpq2GEN(mpq_t Q) {
  pari_sp av = avma;
  return gerepileupto(av, gdiv(mpz2GEN(Q->_mpnum), mpz2GEN(Q->_mp_den));
}

Hope this helps,

    K.B.
--
Karim Belabas                  Tel: (+33) (0)5 40 00 26 17
Universite Bordeaux 1          Fax: (+33) (0)5 40 00 69 50
351, cours de la Liberation    http://www.math.u-bordeaux.fr/~belabas/
F-33405 Talence (France)       http://pari.math.u-bordeaux.fr/  [PARI/GP]
`