Velocity Reviews > A question about taking the absolute value of an integer

# A question about taking the absolute value of an integer

Guest
Posts: n/a

 01-05-2008
I really don't understand how something like..

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

could cause a possible overflow.

Walter Roberson
Guest
Posts: n/a

 01-05-2008
In article <(E-Mail Removed)>,

>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.
-(-3276 ---> 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

Eric Sosman
Guest
Posts: n/a

 01-05-2008
> 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
http://www.velocityreviews.com/forums/(E-Mail Removed)lid

Guest
Posts: n/a

 01-05-2008
On Jan 5, 1:10 pm, Eric Sosman <(E-Mail Removed)> 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
> (E-Mail Removed)

% 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

Coos Haak
Guest
Posts: n/a

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

> On Jan 5, 1:10 pm, Eric Sosman <(E-Mail Removed)> 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
>> (E-Mail Removed)

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

Eric Sosman
Guest
Posts: n/a

 01-05-2008
> On Jan 5, 1:10 pm, Eric Sosman <(E-Mail Removed)> 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
(E-Mail Removed)lid

Richard Tobin
Guest
Posts: n/a

 01-05-2008
In article <(E-Mail Removed)>,

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

Guest
Posts: n/a

 01-06-2008
On Jan 5, 2:29 pm, Eric Sosman <(E-Mail Removed)> wrote:
> > On Jan 5, 1:10 pm, Eric Sosman <(E-Mail Removed)> 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
> (E-Mail Removed)

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

David Thompson
Guest
Posts: n/a

 01-22-2008
On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <(E-Mail Removed)>
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

Coos Haak
Guest
Posts: n/a

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

> On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <(E-Mail Removed)>
> 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