A question about taking the absolute value of an integer

C

Chad

I really don't understand how something like..

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

could cause a possible overflow.
 
W

Walter Roberson

Chad said:
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.
 
E

Eric Sosman

Chad said:
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).
 
C

Chad

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
 
C

Coos Haak

Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:
% 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 ;-(
 
E

Eric Sosman

Chad said:
% 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.
 
R

Richard Tobin

Chad said:
% 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
 
C

Chad

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


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

David Thompson

Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top