Sample functions: mpf_out_raw, mpf_inp_raw

Jim White mathimagics at yahoo.co.uk
Sat Nov 24 20:55:31 CET 2007


> Date: Fri, 23 Nov 2007 21:06:15 -0600
> From: cino hilliard <hillcino368 at hotmail.com>
>
> I wonder why mpf_out_raw and mpf_inp_raw are not
> built in functions like mpz_out_raw and mpz_inp_raw?


For mpz_t's, there are no complications relating to
precision, mpz_inp_raw will automatically resize the
receiving argument if necessary.

For mpf_t's a general facility would require several
options - automatic sizing? automatic truncation? etc

The mpz raw input/output routines are in fact all you
need here. Sample mpf versions are provided below.
Explanatory notes follow.

int mpf_out_raw (FILE *f, mpf_t X) {
   int expt; mpz_t Z; size_t nz;
   expt = X->_mp_exp;
   fwrite(&expt, sizeof(int), 1, f);
   nz = X->_mp_size;
   Z->_mp_alloc = nz; 
   Z->_mp_size  = nz; 
   Z->_mp_d     = X->_mp_d;
   return (mpz_out_raw(f, Z) + sizeof(int));
   }

void mpf_inp_raw  (FILE *f, mpf_t X) { 
   int expt; mpz_t Z; size_t nz;
   mpz_init (Z);
   fread(&expt, sizeof(int), 1, f);
   mpz_inp_raw  (Z, f);
   mpf_set_z    (X, Z); 
   X->_mp_exp   = expt;
   mpz_clear (Z);
   }

Notes:

1. Output is done by writing the exponent, then using
mpz_out_raw to write, the limbs (via a dummy mpz_t set
up to point at those limbs).

2. Input is done by reading the exponent, then using
mpz_inp_raw to load the limbs into a temporary mpz_t.
This is then assigned to the mpf_t variable via
mpf_set_z, and the correct exponent is then set.

3. On input, if the target mpf_t has insufficient
precision, the result is automatically truncated by 
mpz_set_f.  This is particularly useful when one
wishes to generate and store constants at quite a high
precision, and then have an application load them at
variable (lesser) precisions.

On the other hand, the way this is achieved here is
not optimal, of course. The full precision is still
loaded into the temporary mpz_t. 

This would only be a problem at very high precisions,
where it is considered necessary to optimise that
operation - that is, when we want to load just a
specific number of limbs.

One simple method that suggests itself is to use a
format where we write both the exponent and a copy of
the 4-byte size field that mpz_out_raw creates.

The limb array format is big-endian, so our
mpf_inp_raw routine, having decided it needs a reduced
number of limbs loaded, can then simply overwrite the
size marker before making the mpz_inp_raw call.

Cheers

Jim White
MSI, ANU



More information about the gmp-discuss mailing list