Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why int.Max+ int.Max = -2

Tags:

c#

.net

 int a = int.MaxValue;
 int b = int.MaxValue;
 int c = a + b;

Why c=-2always? I have checked in loop also. Its seems garbage value but why -2 only ?

like image 318
Arshad Avatar asked Jul 13 '14 12:07

Arshad


2 Answers

Let's play this with 4-bit integers. The max signed value is 0x7.

0x7 + 0x7 = 14 = 0xE

0xE is one less than the maximum unsigned value 0xF. The maximum unsigned value interpreted as signed is always -1 because adding 1 to it overflows to 0 (just like (-1) + 1 = 0).

So you have (-1) - 1 = -2.

Further note that addition behaves the same way for signed and unsigned integers on a bit-level. That's why I was allowed to jump between signed and unsigned in the above statements.


Here's something different:

int.MaxValue + int.MaxValue = -2
(int.MaxValue + 1) + (int.MaxValue + 1) - 2 = -2
int.MinValue + int.MinValue - 2 = -2
0 - 2 = -2

So why is int.MinValue + int.MinValue = 0? int.MinValue only has the most significant bit set. Doubling int.MinValue therefore just shifts the MSB bit one to the left and out of the integer. The result is 0. Like this:

int.MinValue + int.MinValue = 0
int.MinValue * 2 = 0
int.MinValue << 1 = 0 //int.MinValue is 0x80000000, shift out the left bit

You can use LINQPad to conveniently play with these expressions. You need to wrap them in unchecked so that the C# compiler stops warning you of all the overflows happening here.

As you can see it is possible to intuitively grasp Two's Complement Arithmetic if you play around a little.


How to deal with integer overflow?

  1. Either use a type that can hold the result: (long)int.MaxValue + (long)int.MaxValue.
  2. Or, at least be notified of this probable bug: checked(int.MaxValue + int.MaxValue).
like image 147
usr Avatar answered Oct 25 '22 18:10

usr


Because the result of adding 2 ints with a value of MaxValue together and putting the result into an int overflows what the 32 bits in an int can hold. The result is what you see: -2 due to the resulting bit pattern and the high (sign) bit of the int now being set (called "wrap around"). It is not a random 'garbage' value, but what is to be expected.

Shown in 32 bit binary:

0111 1111 1111 1111 1111 1111 1111 1111         Notice sign bit NOT set (max of signed, 32 bit int)

+

0111 1111 1111 1111 1111 1111 1111 1111          Notice sign bit NOT set (max of signed, 32 bit int)

=

1111 1111 1111 1111 1111 1111 1111 1110            Notice sign bit IS set, making it a negative number

The sum is -2 in Two's complement arithmetic

More explanation here: http://en.wikipedia.org/wiki/Integer_overflow

like image 29
edtheprogrammerguy Avatar answered Oct 25 '22 19:10

edtheprogrammerguy