# A question about taking the absolute value of an integer

Discussion in 'C Programming' started by Chad, Jan 5, 2008.

I really don't understand how something like..

#define abs(x) (((x) < 0) ? -(x) : (x))

could cause a possible overflow.

2. ### Walter RobersonGuest

In article <>,

>I really don't understand how something like..

>#define abs(x) (((x) < 0) ? -(x) : (x))

>could cause a possible overflow.

e.g., INT_MIN might be -32768.
-(-32768) ---> 32768 but INT_MAX might be 32767

This is an issue in any implementation that uses twos complement
(unless it reserves the minimum integral value for some reason,
which would be quite unusual.)

It might help to look at the binary values involved.
On a system with a two-byte unsigned short, for example,
SHORT_MIN would be 0x8000 . To take the negative,
toggle each bit and then add 1 to the result. Toggling each
bit of 0x8000 would be 0x7FFF; add 1 and you get 0x8000 which
is the original value back again.
--
"I was very young in those days, but I was also rather dim."
-- Christopher Priest

Walter Roberson, Jan 5, 2008

3. ### Eric SosmanGuest

> I really don't understand how something like..
>
> #define abs(x) (((x) < 0) ? -(x) : (x))
>
> could cause a possible overflow.

Find a machine where INT_MIN + INT_MAX == -1 (that's
nearly every machine nowadays) and evaluate abs(INT_MIN).

--
Eric Sosman
lid

Eric Sosman, Jan 5, 2008

On Jan 5, 1:10 pm, Eric Sosman <> wrote:
> > I really don't understand how something like..

>
> > #define abs(x) (((x) < 0) ? -(x) : (x))

>
> > could cause a possible overflow.

>
> Find a machine where INT_MIN + INT_MAX == -1 (that's
> nearly every machine nowadays) and evaluate abs(INT_MIN).
>
> --
> Eric Sosman
>

% more abs.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void)
{
printf("%u\n",abs(INT_MIN));
return 0;
}

% ./abs
2147483648

5. ### Coos HaakGuest

Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:

> On Jan 5, 1:10 pm, Eric Sosman <> wrote:
>>> I really don't understand how something like..

>>
>>> #define abs(x) (((x) < 0) ? -(x) : (x))

>>
>>> could cause a possible overflow.

>>
>> Find a machine where INT_MIN + INT_MAX == -1 (that's
>> nearly every machine nowadays) and evaluate abs(INT_MIN).
>>
>> --
>> Eric Sosman
>>

>
>
> % more abs.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <limits.h>
>
> int main(void)
> {
> printf("%u\n",abs(INT_MIN));
> return 0;
> }
>
> % ./abs
> 2147483648

Try printf("%n\n" ....
the result will be a negative number. And an absolute value shall be
positive ;-(
--
Coos

Coos Haak, Jan 5, 2008
6. ### Eric SosmanGuest

> On Jan 5, 1:10 pm, Eric Sosman <> wrote:
>>> I really don't understand how something like..
>>> #define abs(x) (((x) < 0) ? -(x) : (x))
>>> could cause a possible overflow.

>> Find a machine where INT_MIN + INT_MAX == -1 (that's
>> nearly every machine nowadays) and evaluate abs(INT_MIN).

>
> % more abs.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <limits.h>
>
> int main(void)
> {
> printf("%u\n",abs(INT_MIN));
> return 0;
> }
>
> % ./abs
> 2147483648

... which proves -- what, exactly? That two instances
of undefined behavior (one for the overflow, one for the
argument mismatch in printf) always produce a correct result?

Try printing the value of INT_MAX for comparison. Or
try checking the sign of abs(INT_MIN):

printf ("|%d| is %s\n", INT_MIN,
abs(INT_MIN) < 0 ? "negative" : "non-negative");

Here's the point that's sometimes overlooked: "Undefined
behavior" does not mean "The program will crash." It means
the program *may* crash -- or may do something less violent
but still unwelcome, or may do something apparently benign.
It may even do what you expected, on some machines under some
circumstances and for some values of "what you expected."
For example, I expect a certain outcome from the printf
above; the C language does not guarantee the outcome I expect,
but I expect it anyhow. Does that mean it would be a good
idea to *rely* on the expected-but-not-guaranteed behavior?
No, it certainly does not.

--
Eric Sosman
lid

Eric Sosman, Jan 5, 2008
7. ### Richard TobinGuest

In article <>,

>% more abs.c
>#include <stdio.h>
>#include <stdlib.h>
>#include <limits.h>
>
>int main(void)
>{
> printf("%u\n",abs(INT_MIN));
> return 0;
>}
>
>% ./abs
>2147483648

Perhaps you will see your mistake if you change the printf line
to:

printf("%u %u\n",INT_MIN, abs(INT_MIN));

-- Richard
--
:wq

Richard Tobin, Jan 5, 2008

On Jan 5, 2:29 pm, Eric Sosman <> wrote:
> > On Jan 5, 1:10 pm, Eric Sosman <> wrote:
> >>> I really don't understand how something like..
> >>> #define abs(x) (((x) < 0) ? -(x) : (x))
> >>> could cause a possible overflow.
> >> Find a machine where INT_MIN + INT_MAX == -1 (that's
> >> nearly every machine nowadays) and evaluate abs(INT_MIN).

>
> > % more abs.c
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <limits.h>

>
> > int main(void)
> > {
> > printf("%u\n",abs(INT_MIN));
> > return 0;
> > }

>
> > % ./abs
> > 2147483648

>
> ... which proves -- what, exactly? That two instances
> of undefined behavior (one for the overflow, one for the
> argument mismatch in printf) always produce a correct result?
>
> Try printing the value of INT_MAX for comparison. Or
> try checking the sign of abs(INT_MIN):
>
> printf ("|%d| is %s\n", INT_MIN,
> abs(INT_MIN) < 0 ? "negative" : "non-negative");
>
> Here's the point that's sometimes overlooked: "Undefined
> behavior" does not mean "The program will crash." It means
> the program *may* crash -- or may do something less violent
> but still unwelcome, or may do something apparently benign.
> It may even do what you expected, on some machines under some
> circumstances and for some values of "what you expected."
> For example, I expect a certain outcome from the printf
> above; the C language does not guarantee the outcome I expect,
> but I expect it anyhow. Does that mean it would be a good
> idea to *rely* on the expected-but-not-guaranteed behavior?
> No, it certainly does not.
>
> --
> Eric Sosman
>

When I posted the code, I was missing the bigger picture at the time.
After sitting and thinking about the whole thing, I finally "got it".

9. ### David ThompsonGuest

On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <>
wrote:

> Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:

> > printf("%u\n",abs(INT_MIN));

<snip: appears to work>

> Try printf("%n\n" ....
> the result will be a negative number. And an absolute value shall be
> positive ;-(

%d or %i. %n is something quite different, and wrong here.

- formerly david.thompson1 || achar(64) || worldnet.att.net

David Thompson, Jan 22, 2008
10. ### Coos HaakGuest

Op Tue, 22 Jan 2008 05:22:40 GMT schreef David Thompson:

> On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <>
> wrote:
>
>> Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:

>
>>> printf("%u\n",abs(INT_MIN));

> <snip: appears to work>
>
>> Try printf("%n\n" ....
>> the result will be a negative number. And an absolute value shall be
>> positive ;-(

>
> %d or %i. %n is something quite different, and wrong here.
>

Absolutely, thanks.
--
Coos

Coos Haak, Jan 22, 2008