mpz_get_si: possible undefined behaviour? [Was: Micro-GMP]
Vincent Lefevre
vincent at vinc17.net
Tue Dec 4 01:31:55 UTC 2018
On 2018-12-03 23:47:00 +0100, Marco Bodrato wrote:
> If LONG_MIN == -LONG_MAX-1, this step is correct.
> But, what about the LONG_MIN == -LONG_MAX case?
> The result is undefined, isn't it?
Yes.
> Which value we should actually return when the given mpz does not
> fit in the target type is not so well defined nor important,
One issue is that the function is poorly specified, if not buggy:
-- Function: signed long int mpz_get_si (const mpz_t OP)
If OP fits into a `signed long int' return the value of OP.
Otherwise return the least significant part of OP, with the same
sign as OP.
But on LONG_MAX + 1, mpz_get_si will give 0:
if (size > 0)
return zl & LONG_MAX;
while mathematically (and for mpz_sgn), 0 does not have the same sign
as a positive integer.
> but triggering an undefined behaviour seems a bad idea anyway.
>
>
> I'd suggest to substitute "-1" with "(LONG_MIN + LONG_MAX)", I mean
> something like:
>
> return (LONG_MIN + LONG_MAX) -
> (long) ((zp[0] - (-LONG_MAX - LONG_MIN)) & LONG_MAX);
>
>
> Comments about this analysis or better solutions?
I would write for clarity:
long c = LONG_MIN + LONG_MAX; /* -1 or 0 */
/* ... */
return c - (long) ((zp[0] - (-c)) & LONG_MAX);
and update the "Otherwise" case of the description, to say that the
returned value can be 0.
--
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
More information about the gmp-devel
mailing list