5

I know, Int32.MaxValue * Int32.MaxValue will yield a number larger than Int32; But, shouldn't this statement raise some kind of an exception?

I ran across this when doing something like IF (X * Y > Z) where all are Int32. X and Y are sufficiently large enough, you get a bogus value from X * Y.

Why is this so and how to get around this? besides casting everything to Int64.

shA.t
  • 16,580
  • 5
  • 54
  • 111
Greg Balajewicz
  • 183
  • 2
  • 9

6 Answers6

26

Because int32 confines the results to 32bits.

So, if you have a look at the math at a byte level.

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001

As you can see, the lowest 4 bytes = 1.

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
19

By default, C# arithmetic is done in an unchecked context, meaning values will roll over.

You can use the checked and unchecked keywords to control that behavior.

Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
  • Just ran into a scenario where int.maxvalue + 1 was int.minvalue...I was scratching my head so hard with that one until realized it must be rolling over! – richard May 17 '13 at 04:07
8

It's interesting to note that this works regardless of the base you use:

(n-1)*(n-1)  mod n 
n^2 - 2n + 1 mod n
0   -  0 + 1 mod n
           1 mod n
BCS
  • 75,627
  • 68
  • 187
  • 294
6

You have to ask for it:

checked {
    int a = int.MaxValue;
    int b = int.MaxValue;
    int c = a * b;    // kaboom
}
shA.t
  • 16,580
  • 5
  • 54
  • 111
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
6

You have disabled the overflow checks in your project. With checked mode On it will throw an exception.

munissor
  • 3,755
  • 22
  • 24
  • thank you for your responses! I did not disable the overflow check; where is this setting in Visual Studio ? – Greg Balajewicz Jun 08 '10 at 20:48
  • I'don't have a copy of VS here but if I remember well it's in the Advanced compiler options (Right click on a project and then Properties -> Build -> Advanced) – munissor Jun 08 '10 at 21:31
2

Int32.MaxValue (using the value given here) is 2,147,483,647.

In base 2, that is: 111 1111 1111 1111 1111 1111 1111 1111... 2^31-1. The first bit is the sign bit.

If you multiply that by itself, you get: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

Going back to the original problem of "why is it 1?", since Integer.MaxValue is the maximum value, that causes an integer overflow. The result is truncated to the lowest 31 bits, which is all 0s plus 1.

Edit: Here is a tutorial on binary multiplication. Using a simple case of all 1s: 111 * 111

you get: 00111 01110 + 11100 = 100001

You can expand this for the case of Int32.MaxValue. I shortened it to 3 digits for brevity.

Also, as another answer said, in C# these overflows will occur by default.

Community
  • 1
  • 1
David
  • 1,187
  • 1
  • 10
  • 22
  • A good treatment for thous who need it, but the OP was wondering why C# didn't catch it and throw an error. – BCS Jun 08 '10 at 20:47