New mini-gmp macro GMP_CMP?

Niels Möller nisse at
Wed Nov 23 22:28:51 UTC 2016

"Marco Bodrato" <bodrato at> writes:

> Il Mar, 22 Novembre 2016 9:32 am, Niels Möller ha scritto:
>> I was looking at how to simplify mini-gmp's mpz_cmp_si. I considered
>> using mpz_cmpabs_ui to handle the case of both inputs negative, which
> Using cmpabs_ui you can reduce from four cases in cmp_si to three, correct?
> Not a bad idea, IMO.

Right, it would be

  mpz_cmp_si (const mpz_t u, long v)
    if (v >= 0) 
      return mpz_cmp_ui (u, v);
    else if (u->_mp_size >= 0)
      return 1;
      return - mpz_cmpabs_ui (u, GMP_NEG_CAST(mp_limb_t, v));

If we *really* go for conciseness, we could do something like

  mpz_cmp_si (const mpz_t u, long v)
    long sign = - (u->_mp_size < 0);
    if ((sign ^ v) >= 0) 
      sign *= mpz_cmpabs_ui (u, ABS_GMP_CAST(mp_limb_t, v));
    return sign;

But we shouldn't try to be too clever.

>> !     return GMP_CMP (mpz_get_ui (u), v);
>>   }
> With this changes we leave to the compiler the task of inlining mpz_get_ui
> and detect the common parts... the full task of code optimisation.

I think we can leave that to the compiler. I'd suspect mpz_get_ui is
inlined (but I haven't checked). And if it isn't, these are O(1)
operations which typically aren't used in tight loops.

> If we decide for this approach, we may also
> #define GMP_CMP(a,b) (((a) < (b)) ? -1 : ((a) > (b)))
> It is not as elegant as, nor symmetric, but maybe it's easier to understand.

I like your symmetric version; once you get it it's clear and obvious. I
haven't looked at the generated code, it's not obvious if there's going
to be a difference, or in which way. If we try to help the compiler
optimize, we'd want to avoid branches.


Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.

More information about the gmp-devel mailing list