ABS_CAST

Niels Möller nisse at lysator.liu.se
Tue Mar 27 12:05:35 CEST 2012


I had a look at the ABS_CAST macro introduced a while ago,

  #define ABS_CAST(T,x) ((x) >= 0 ? (T)(x) : -((T)((x) + 1) - 1))

As I understand it, the point is that, e.g.,

  int x;
  unsigned absx;
  ...
  absx =  ABS_CAST (unsigned, x);

should give the right result for x = INT_MIN (where plain ABS would give
the result INT_MIN). And be more portable than the simpler definition

  #define ABS_CAST(T, x) ((T) ABS(x))

But the current definition seems strange. When x < 0, it will cast the
negative value to an unsigned type (which I suspect is not portable
according to the C89 spec (maybe it's more well defined in C99?)), and
I'm not sure what is gained by the extra +1 and -1 when doing that. I'd
suggest using instead

  #define ABS_CAST(T,x) ((x) >= 0 ? (T)(x) : (((T)(-((x) + 1))) + 1))

Then in the case x < 0, first add 1, and note that both (x+1) and -(x+1)
always fit in a signed int. Then negate, cast the resulting
*non-negative* number to unsigned, and then an unsigned add of 1 to get
the correct absolute value.

Am I misunderstanding anything here?

Regards,
/Niels

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



More information about the gmp-devel mailing list