mpz_{eq,lt,gt}_{ui,si}_p macros?

Marc Glisse marc.glisse at inria.fr
Thu Feb 14 20:15:08 CET 2013


On Thu, 14 Feb 2013, bodrato at mail.dm.unipi.it wrote:

> Il Mer, 13 Febbraio 2013 9:28 am, Marc Glisse ha scritto:
>> On Wed, 13 Feb 2013, bodrato at mail.dm.unipi.it wrote:
>
>>> Are inline functions as portable as macros?
>>
>> Not quite, but I don't know any current compiler that doesn't support
>> them. Besides, I thought we were talking about __builtin_constant_p, and
>> thus gcc (or compatible compilers).
>
> If we define the symbols in gmp.h, we should also document them: functions
> or macros?
> In the #if GCC case, we can define the corresponding _mpz inline
> functions; but I'd like to avoid adding function calls in the #else case.

We already use static inline functions in gmp-impl.h for all compilers. 
But maybe configure adds flags that put the compiler in a special mode 
(C99?) and the compiler might not like inlines otherwise?

>>> Assume we write cmp_ui (z,limb) as gt()?1:lt()?-1:0
>
>> I tested (i>0?1:i<0?-1:0)<0 (and >0 and ==0) and gcc optimized it to just
>> i<0 (resp. i>0, i==0).
>
> Great!
> The problem arises if gt() and lt() are not so simple.

Indeed. It does seem that your specialized lt/gt/eq macros are needed to 
get optimal code.

>>>>> variants, I'm not sure I'm handling correctly the negative constants.
>
>> If -(SI) is the only issue, then -(unsigned long)(SI) should work, no?
>
> Maybe...
>
> It is nearly unreadable...
>
> #define mpz_lt_si_p(Z,SI)						\
>  (__builtin_constant_p ((SI) >= 0) && (SI) >= 0			\
>   ? mpz_lt_ui_p(Z, __GMP_CAST (unsigned long, SI))			\
>   : __builtin_constant_p ((SI) <= 0 && -__GMP_CAST (unsigned long, SI) <=
> GMP_NUMB_MAX)\
>   && ((SI) <= 0 && -__GMP_CAST (unsigned long, SI) <= GMP_NUMB_MAX)	\
>   ? (Z)->_mp_size < -((Z)->_mp_d[0] <=-__GMP_CAST (unsigned long, SI))	\
>   : _mpz_cmp_si (Z,SI) < 0)

Some things that could help with readability:
* make it an inline function ;-)
* Niels' _GMP_CST_TRUE_P macro
* a gcc statement expression would let you use local variables

> ... and perhaps I should add one more cast to mp_limb_t before the
> comparison with _mp_d[0]...

That doesn't seem necessary.

-- 
Marc Glisse


More information about the gmp-devel mailing list