labs(LONG_MIN)
Author Message
labs(LONG_MIN)

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?
--

Mon, 10 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

Quote:

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

According to my reading of the man page ( oops, UNIX-specific,
sorry guys ;-) ), it's because abs or labs may have to return the
same negative integer that was passed to it, so it had better return
a signed value:

Note: A twos-complement integer can hold a negative number whose
absolute value is  too large for the integer to hold.  When
given this largest negative value, the abs subroutine returns
the same value.

--

--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

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?

-(unsigned long)LONG_MIN

-- Mat.
--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

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?

Would (LONG_MAX + 1UL) work?

--
Clark S. Cox, III

If you1re not part of the solution, you1re part of the precipitate.
-- Steven Wright
--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

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?

Wouldn't -((unsigned long)LONG_MIN) do?

Richard
--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

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.

Correct.

Quote:
> So I came up with (((unsigned long) -(LONG_MIN + 1)) + 1).
> This looks overly complex; is there a better way?

That's about as good as anything.  Most compilers will peform
the constant folding, so it's also as efficient as anything.
--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

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
--

Thu, 13 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

Quote:

> So this is legal code in C:

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

Don't you have to cast one of the values to unsigned long before

Quote:
> On the other hand this seems much simpler:

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

Here too, isn't LONG_MAX + 1 still signed long?
--

Fri, 14 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

wrote in comp.lang.c.moderated:

Quote:

> > So this is legal code in C:

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

> Don't you have to cast one of the values to unsigned long before

> > On the other hand this seems much simpler:

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

> Here too, isn't LONG_MAX + 1 still signed long?

--

Sat, 15 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

wrote in comp.lang.c.moderated:

Quote:

> > So this is legal code in C:

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

> Don't you have to cast one of the values to unsigned long before

> > On the other hand this seems much simpler:

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

> Here too, isn't LONG_MAX + 1 still signed long?

Sorry, bad hair day.  You are correct.

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

--and--

ul = -LONG_MAX == LONG_MIN ? (unsigned long)LONG_MAX : (unsigned
long)LONG_MAX + 1;

Thanks.

Jack Klein
--
Home: http://jackklein.home.att.net
--

Sat, 15 Feb 2003 03:00:00 GMT
labs(LONG_MIN)

Quote:

>   -(unsigned long)LONG_MIN

Thanks!  I didn't remember that casting a negative value to
unsigned is fully defined.
--

Sat, 15 Feb 2003 03:00:00 GMT

 Page 1 of 1 [ 12 post ]

Relevant Pages