[PPL-devel] [Fwd: Re: Bug affecting mpq_class::get_num() and mpq_class::get_den()?]

Roberto Bagnara bagnara at cs.unipr.it
Mon Jun 10 12:49:09 CEST 2002


Dear Gerardo,

I am forwarding this to the mailing list as I am sure others
are interested in this issue.

If I understand correctly, in GMP 4.0.1 and 4.1 there
is no way to obtain an mpz_class& (or const mpz_class&)
to the numerator or denominator of an mpq_class, right?
In other words, is it correct to say that numerator and
denominator as mpz_class objects can only be obtained
by making copies?
All the best

     Roberto


-------- Original Message --------
Subject: Re: Bug affecting mpq_class::get_num() and mpq_class::get_den()?
Date: Mon, 10 Jun 2002 12:20:24 +0200
From: gerardo.ballabio at unimib.it (Ballabio Gerardo - Dip. di Scienza dei Materiali)
To: Kevin Ryde <user42 at zip.com.au>
CC: Roberto Bagnara <bagnara at cs.unipr.it>, Torbjorn Granlund <tege at swox.se>
References: <87k7p9bdqi.fsf at zip.com.au>

On 2002.06.09 00:35 Kevin Ryde wrote:
 > This bug report looks real unfortunately.  Is it perhaps due to the
 > difference between "mpz_classref" and "mpz_class&"?
 > mpz_class::get_num seems to work in other simpler contexts.

 > $ g++ -W -Wall -c gmpbug.cc
 > gmpbug.cc: In function `mpz_class& numerator(mpq_class&)':
 > gmpbug.cc:24: could not convert `__gmp_expr<__gmpq_value,
 >    __gmpq_value>::get_num()' to `mpz_class&'
 >
 > #include <gmpxx.h>
 >
 > mpz_class&
 > numerator(mpq_class& r) {
 >   return r.get_num();
 > }

Yes, you got the point.
"mpz_classref" is not the same as "mpz_class &", and I can't define a
conversion from "mpz_classref" to "mpz_class &" because there's _no_
"mpz_class" to be referenced!
Indeed, such an "mpz_class" could only be a temporary object, and it
wouldn't be correct to take a reference to it -- as soon as the
temporary goes out of scope (in your example, as soon as numerator()
is exited and the reference is returned!), the reference is broken.
(Furthermore, in the current implementation, creating an mpz_class
from an mpz_t makes a _copy_ of the original mpz_t, thus we could
read but not write to it!)

As far as I can see, the only way out is to add two mpz_classes to
the representation of mpq_class, and "symlink" the two underlying
mpz_t's to the mpq_t (or remove the mpq_t and rewrite all mpq
operations in terms of mpz operations, but I don't think we want to):
then we can throw away mpz_classref, and reference the two
mpz_classes directly.
That would also be a considerable simplification of the
implementation; but I don't know very much about the internals of
mpz_t and mpq_t, and I'm not sure that such "symlinking" can be done
(actually, I looked into gmp.h, but I'm quite confused about mpz_t
being defined as "typedef __mpz_struct mpz_t[1];").

Otherwise, I can only suggest to leave the code as it is, and to
change the documentation like this:

     mpz_classref mpq_class::get_num ()
     mpz_classref mpq_class::get_den ()

     Get an `mpz_classref' referencing to the numerator or denominator
of an
     `mpq_class'.  This can be used both for read and write access.
If the object
     returned is modified, it modifies the original `mpq_class'.

     `mpz_classref' is an internal GMP++ type acting like an
`mpz_class &'. You can
     use it as if it were an `mpz_class', except that you can't take a
reference to
     that (nonexisting) `mpz_class' -- this includes passing it to a
function that
     requires an `mpz_class &' argument.

Do you feel this is too big a limitation?

Gerardo


-- 
Prof. Roberto Bagnara
Computer Science Group
Department of Mathematics, University of Parma, Italy
http://www.cs.unipr.it/~bagnara/
mailto:bagnara at cs.unipr.it




More information about the PPL-devel mailing list