New mini-gmp macro GMP_CMP?
Niels Möller
nisse at lysator.liu.se
Wed Nov 23 22:28:51 UTC 2016
"Marco Bodrato" <bodrato at mail.dm.unipi.it> 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
int
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;
else
return - mpz_cmpabs_ui (u, GMP_NEG_CAST(mp_limb_t, v));
}
If we *really* go for conciseness, we could do something like
int
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.
Regards,
/Niels
--
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