(INT_MIN -1) > 0 equals to 0??

A

Andy

Hello All,

I have an overflow problem regarding INT_MIN. When I print out
INT_MIN-1, it equals to 2147483647, which is greater than 0. But when
I compare it with 0, like (INT_MIN-1)>0. gcc just gives 0 value, is
2147483647 supposed to be bigger than 0? I am confused. For testing
purpose, my code is as follows:

#include <stdio.h>
#include <limits.h>

int main(){
int i = INT_MIN;
int j = i-1;
int cmp = ((i-1)>0);
printf("j=%d, cmp=%d", j, cmp);
return 0;
}

$ j=2147483647, cmp=0

Thanks for help me out...

~Andy W.
 
J

James Dow Allen

Hello All,
int i = INT_MIN;
int j = i-1;
int cmp = ((i-1)>0);
printf("j=%d, cmp=%d", j, cmp);

$ j=2147483647, cmp=0

My guess is that the compiler looked at "i-1>0"
and simplified it to "i > 1" which is of course false.

If this seems wrong or invalid, remember that you started the
invalidity, "drawing first blood" by subtracting one from a
number already defined as being as negative as possible!

The specific help I'd offer to you, as well as many others who
post here, wondering what p++ = ++p++ does, is ...
learn to write VALID C code, for heaven's sakes!
When you can do that, understanding why invalid code does
invalid things will be easy.
Thanks for help me out...

Glad to be of help.
James Dow Allen
 
G

gwowen

As already pointed out, this is due to compiler optimisations enabled
by the standard not mandating what happens when you overflow a signed
integer type. (On GCC 4.2.1, it gives different results at -O0 and -
O3).

As you're using GCC, if you *need* to rely on two's complement, see
the

-fwrapv
-fstrict-overflow

compiler options.
 
A

Andy

My guess is that the compiler looked at  "i-1>0"
and simplified it to "i > 1" which is of course false.

If this seems wrong or invalid, remember that you started the
invalidity, "drawing first blood" by subtracting one from a
number already defined as being as negative as possible!

Thanks for your help. The reason why I am doing this is: I have a
variable, which is initialized into INT_MIN. Later, I could add a
positive or negative value to INT_MIN, and this addition could be
repeated for couple of times. For example:

initial: INT_MIN
1 step: INT_MIN+3
2 step: INT_MIN+5
3 step: INT_MIN-20
......
......

What I want to do is to define a MACRO to compute the right value:

#define NEG_ADD(x, y) ((x<0)&&(y<0)&&(x+y)>0 ? INT_MIN : (x+y))

But this one does not work. Any advice? Thanks again!
 
W

Willem

Andy wrote:
) Thanks for your help. The reason why I am doing this is: I have a
) variable, which is initialized into INT_MIN. Later, I could add a
) positive or negative value to INT_MIN, and this addition could be
) repeated for couple of times. For example:
)
) initial: INT_MIN
) 1 step: INT_MIN+3
) 2 step: INT_MIN+5
) 3 step: INT_MIN-20
) .....
) .....
)
) What I want to do is to define a MACRO to compute the right value:
)
) #define NEG_ADD(x, y) ((x<0)&&(y<0)&&(x+y)>0 ? INT_MIN : (x+y))
)
) But this one does not work. Any advice? Thanks again!

Reverse the check.
(x + y) < INT_MIN
can be written as:
x < (INT_MIN - y)
You of course also need y<0 to avoid overflow, but if y>0 then
there will be no overflow, so this detects overflow:
(y < 0) && (x < (INT_MIN - y))

Additionally, I'd like to point out that you want to enclose all
occurrences of x and y with parens in your macro, for safety.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
K

Keith Thompson

Andy said:
Thanks for your help. The reason why I am doing this is: I have a
variable, which is initialized into INT_MIN. Later, I could add a
positive or negative value to INT_MIN, and this addition could be
repeated for couple of times. For example:

initial: INT_MIN
1 step: INT_MIN+3
2 step: INT_MIN+5
3 step: INT_MIN-20
.....
.....

What I want to do is to define a MACRO to compute the right value:

#define NEG_ADD(x, y) ((x<0)&&(y<0)&&(x+y)>0 ? INT_MIN : (x+y))

But this one does not work. Any advice? Thanks again!

There is no right value for INT_MIN-20. Evaluating that expression
invokes undefined behavior.

There are ways, given the values of x and y, to determine whether x+y
will overflow without actually adding them. The question is, what do
you want to do if the result is going to overflow?

It looks like you want to return INT_MIN rather than the correct
mathematical value.

For example, assuming INT_MIN == -32768, I *think* you want:

NEG_ADD(-32768, +1) == -32767
NEG_ADD(-32768, -1) == -32768

This is sometimes called saturating arithmetic.

Is that what you're trying to do?

Your macro is not the way to do this, since the computation of x+y
invokes undefined behavior before you can compute a correct result.
 
A

Andy

Andy wrote:

) Thanks for your help. The reason why I am doing this is: I have a
) variable, which is initialized into INT_MIN. Later, I could add a
) positive or negative value to INT_MIN, and this addition could be
) repeated for couple of times. For example:
)
) initial: INT_MIN
) 1 step: INT_MIN+3
) 2 step: INT_MIN+5
) 3 step: INT_MIN-20
) .....
) .....
)
) What I want to do is to define a MACRO to compute the right value:
)
) #define NEG_ADD(x, y) ((x<0)&&(y<0)&&(x+y)>0 ? INT_MIN : (x+y))
)
) But this one does not work. Any advice? Thanks again!

Reverse the check.
  (x + y) < INT_MIN
can be written as:
  x < (INT_MIN - y)
You of course also need y<0 to avoid overflow, but if y>0 then
there will be no overflow, so this detects overflow:
  (y < 0) && (x < (INT_MIN - y))

Additionally, I'd like to point out that you want to enclose all
occurrences of x and y with parens in your macro, for safety.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Great, problem solved... Thanks!
 
C

CBFalconer

As already pointed out, this is due to compiler optimisations
enabled by the standard not mandating what happens when you
overflow a signed integer type. (On GCC 4.2.1, it gives
different results at -O0 and - O3).

Not so. The standard states that an overflow in a signed integer
type causes undefined behaviour.
 
K

Keith Thompson

CBFalconer said:
Not so. The standard states that an overflow in a signed integer
type causes undefined behaviour.

Yes, it does, but that doesn't contradict what gwowen wrote, which
was, as far as I can see, entirely correct. (One might claim that
discussions of gcc's behavior are off-topic, but the point was to
explain a particular symptom of undefined behavior.)
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top