Bill Allombert on Wed, 05 Dec 2007 00:35:24 +0100


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

Re: Can PARI use GNU MP integers and rationals?


On Wed, Dec 05, 2007 at 12:19:44AM +0100, Karim Belabas wrote:
> * 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! */
> }

It is preferable to use the t_INT API (src/kernel/none/int.h),  so it
also work with the native PARI kernel.

> 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];
> }

Idem.

Cheers,
Bill