views:

347

answers:

12

Given this code:

int x = 20000;
int y = 20000;
int z = 40000;

// Why is it printing WTF? Isn't 40,000 > 32,767?
if ((x + y) == z) Console.WriteLine("WTF?");

And knowing an int can hold −32,768 to +32,767. Why doesn't this cause an overflow?

+10  A: 

http://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx

Type: int Range: -2,147,483,648 to 2,147,483,647

Scoregraphic
Downvoted because the answer isn't complete. See the answer that describes checked arithmetic.
jasonh
The answer is complete in regard of the original question (why is there no overflow). So in my opinion, a downvote is wrong. But do an upvote on your prefered solution instead.
Scoregraphic
+1  A: 

Because ints are 32-bit, holding values up to ±2GB.

Vinay Sajip
Correct answer, except for the use of GB -- integers have nothing to do with bytes per se; this should have read ±2G. ;)
stakx
+2  A: 

In C#, an Int is 4 bytes. So it maxes out at 2^31 or 2,147,483,648. If you want a 2 byte integer, use a short instead of an int.

Jeff Siver
+1  A: 

An int's size is 4 byte so it can hold at least 2^31 which is around 2 billion.

Gábor Hargitai
+1  A: 

The int keyword maps to the .NET Framework Int32 type, which can hold integers in the range from -2,147,483,648 to 2,147,483,647.

CMS
+1  A: 

in C# int (System.Int32) is of 32 bits which can happily store this value.

this. __curious_geek
+2  A: 

Because an int in .NET is a signed 32 bit number with a range of -2,147,483,648 to 2,147,483,647.

Reference : http://msdn.microsoft.com/en-us/library/5kzh1b5w(VS.80).aspx

Maltrap
+1  A: 

you are given to print the result as "WTF?" .Then how should it display other value.

Int means int32 its range is –2147483648 to 2147483647 you are given the range of int16 :–32768 to 32767

This is the reason it is not throwing any error

anishmarokey
+6  A: 

While everyone is correct in saying that an "int" type on a 32 bit machine is most likely 2^32, there is a glaring flaw in your methodology.

Let's assume that int was 16 bit. You're assigning a value that will overflow z, so z itself is overflowed. When you calculate x+y you're also overflowing the int type, it's very likely that both cases will overflow to the same value, meaning you'd hit your equality regardless(this is probably compiler dependent, I'm not quite sure whether x+y will be promoted).

The correct way to do your experiment would be for z to have a larger data type than x and y. For example(Sorry for plain C, I'm not much of C# person. Hopefully it illustrated the methodology, however.)

int x = INT_MAX;
int y = INT_MAX;
int sum = x + y;
long long z = INT_MAX+INT_MAX;
if(sum == z) 
 printf("Why didn't sum overflow?!\n");

Comparing sum and z is important as comparing x+y and z may still come out fine depending on how the compiler handles promotion.

Falaina
Great C example. I actually got this off of a C guy's blog, but asked it in C# because were on SO and it gave the same result.
Lucas McCoy
+1  A: 

First of all your code is in the range for int... However if it were not in the range then it wont complain either... coz you are never assigning a value back to any variable after doing X+Y in your if check...

Suppose if you were doing X * Y then it'll be calculated and the result would be a long value then the value from variable Z is taken and promoted to a long then both would be compared... Remember the casting from a lower range primitive to upper range primitive value is implicit.

int x = 200000; //In your code it was 20000
int y = 200000; //In your code it was 20000
int z = 40000;

// Why is it printing WTF? Isn't 40,000 > 32,767?
// Note: X + Y = 200000 and not < 32,767 
// would pass compiler coz you are not assigning and values are compared as longs
// And since it's not equals to 40,000 the WTF did not got printed
if ((x + y) == z) Console.WriteLine("WTF?");     
// And x * y >= z is true WTF MULTIPLY got printed
if ((x * y) >= z) Console.WriteLine("WTF MULTIPLY?"); 
// Compiler would fail since x can't hold 40,00,00,00,000
x = x * y;
S M Kamran
+19  A: 

In C#, the int type is mapped to the Int32 type, which is always 32-bits, signed.

Even if you use short, it still won't overflow because short + short returns an int by default. If you cast this int to short - (short)(x + y) - you'll get an overflowed value. You won't get an exception though. You can use checked behavior to get an exception:

using System;

namespace TestOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            short x = 20000;
            short y = 20000;
            short z;

            Console.WriteLine("Overflowing with default behavior...");
            z = (short)(x + y);
            Console.WriteLine("Okay! Value is {0}. Press any key to overflow " +
                "with 'checked' keyword.", z);
            Console.ReadKey(true);

            z = checked((short)(x + y));
        }
    }
}

You can find information about checked (and unchecked) on MSDN. It basically boils down to performance, because checking for overflow is a little bit slower than ignoring it (and that's why the default behavior is usually unchecked, but I bet that in some compilers/configurations you'll get an exception on the first z assignment.)

Blixt
+1 I'd just add Scoregraphic's link here to make it a complete and great answer.
Vinko Vrsalovic
Thanks for the tip, I added some links to Int32, int and short types =)
Blixt
A: 

All the above is true, however, it's important to know, that if you assign a nubmer grater than 2^32, it will not compile!

Clangon