Bitwise logic gmpxx.h problems

joppe.bos at epfl.ch joppe.bos at epfl.ch
Fri Jul 25 18:23:59 CEST 2008


Quoting Torbjorn Granlund <tg at swox.com>:
> Marc Glisse <marc.glisse at normalesup.org> writes:
>
>   On Thu, 24 Jul 2008, Joppe Bos wrote:
>
>   > I am not an experienced C++ hacker but the problem of these
>   > compiler errors are the following lines in gmpxx.h:
>   >
>   > __GMPP_DECLARE_COMPOUND_OPERATOR(operator&=)
>   > __GMPP_DECLARE_COMPOUND_OPERATOR(operator|=)
>   > __GMPP_DECLARE_COMPOUND_OPERATOR(operator^=)
>   >
>   > __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
>   > __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
>   > __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
>   >
>   > Replacing the double PP and ZZ by single ones solves the problem.
>
>   It seems mostly right, except that we now get (experimentally)
>   operator&=(double) which silently forwards to operator&=(unsigned long). I
>   don't really like that. I would prefer if it either generated an error
>   (which can be achieved by separating the float/double from the other
>   int/short/etc in the macros) or cast the double to a mpz_class (either
>   play with the macros to do this cast, or provide yet another overload for
>   the eval method).
>
> Does mpz_a &= double work differently from mpz_a = mpz_a & double?
> That'd be bad!
>
> I suppose mpz_a $= double (for any operation $) should work like
>
>   mpz_b = double   [using mpz_set_d]
>   mpz_a $= mpz_b

As far as I can tell the operator&=(double) gets indeed forwarded to  
operator&=(unsigned long) but I think, I am not 100% sure, this is  
done by casting the value. In other words it gets casted (truncated)  
and this is exactly what mpz_set_d does. If this is true then the  
current situation works perfectly. I have done multiple tests and  
never found any strange behavior (but this obviously doesn't mean it  
works).

If one wants to change this behavior in order to avoid confusion I opt  
for "yet another overload for the eval method". But then we need to do  
this as well for all the three functions: operator^=, operator|= and  
operator&=. Implementing it only for "double" is very straightforward;  
just reuse the code in the mail from Torbjorn and replace the  
"unsigned long int i" with "double i" and the mpz_set_ui with a  
mpz_set_d statement.

Regards,

Joppe



More information about the gmp-bugs mailing list