wrote in comp.lang.c.moderated:

Quote:

> I need the absolute value of LONG_MIN, as an unsigned long. The

> obvious expression would be (unsigned long) -LONG_MIN, but the value

> of that is unspecified because -LONG_MIN normally overflows. So I

> came up with (((unsigned long) -(LONG_MIN + 1)) + 1). This looks

> overly complex; is there a better way?

> Also, why does abs() return a signed integer?

First realize that there is no guarantee that ULONG_MAX is greater

than LONG_MAX. The only C integral type for which the unsigned type

is guaranteed to hold values greater than the maximum value of the

signed type is unsigned char vs. signed char.

Next realize that there is no requirement or guarantee that the

absolute value of LONG_MIN is greater than that of LONG_MAX. In two

of the three permitted types of integer representation (signed

magnitude and 1's complement) they are in fact the same. In 2's

complement representation it is possible, but not required, for the

absolute value of LONG_MIN to be 1 greater than LONG_MAX.

Next consider that there are only two possible cases for XXX_MIN and

XXX_MAX, where XXX is any signed integral type in C:

XXX_MIN == -XXX_MAX or XXX_MIN == (-XXX_MAX) -1;

So this is legal code in C:

unsigned long ul = LONG_MAX + (-LONG_MAX - LONG_MIN);

On the other hand this seems much simpler:

ul = -LONG_MAX == LONG_MIN ? LONG_MAX : LONG_MAX + 1;

In either case the resulting value in the unsigned long will be 0L if

LONG_MAX == ULONG_MAX, which is allowed.

Jack Klein

--

Home: http://jackklein.home.att.net

--