Reputation: 2613
To my understanding, that should give you an overflow error and when I write it like this:
public static void Main()
{
Console.WriteLine(int.MaxValue - int.MinValue);
}
it does correctly give me an overflow error.
However:
public static void Main()
{
Console.WriteLine(test());
}
public static Int32 test(int minimum = int.MinValue, int maximum = int.MaxValue)
{
return maximum - minimum;
}
will output -1 Why does it do this? It should throw an error because its clearly an overflow!
Upvotes: 36
Views: 17677
Reputation: 2497
I think it goes even further than overflows.
if i look at this
Int64 max = Int32.MaxValue;
Console.WriteLine(max.ToString("X16")); // 000000007FFFFFFF
Int64 min = Int32.MinValue;
Console.WriteLine(min.ToString("X")); //FFFFFFFF80000000
Int64 subtract = max - min;
Console.WriteLine(subtract.ToString("X16")); //00000000FFFFFFFF <- not an overflow since it's a 64 bit number
Int32 neg = -1
Console.WriteLine(neg.ToString("X")); //FFFFFFFF
Here you see that if you just subtract the hex values) in 2's complement you get the number that's -1 in a 32 bit number. (after trunkating the leading 0's
2's complement arithmetic can be very fun http://en.wikipedia.org/wiki/Two's_complement
Upvotes: 2
Reputation: 172548
int.MaxValue - int.MinValue
= a value which int cannot hold. Thus, the number wraps around back to -1.
It is like 2147483647-(-2147483648) = 4294967295 which is not an int
The value of this constant is -2,147,483,648; that is, hexadecimal 0x80000000.
The value of this constant is 2,147,483,647; that is, hexadecimal 0x7FFFFFFF.
From MSDN
When integer overflow occurs, what happens depends on the execution context, which can be checked or unchecked. In a checked context, an OverflowException is thrown. In an unchecked context, the most significant bits of the result are discarded and execution continues. Thus, C# gives you the choice of handling or ignoring overflow.
Upvotes: 55
Reputation: 12811
The default project-level setting that controls this is set to "unchecked" by default. You can turn on overflow checking by going to the project properties, Build tab, Advanced button. The popup allows you to turn on overflow checking. The .NET Fiddle tool that you link to seems to perform some additional static analysis that is preventing you from seeing the true out-of-the-box runtime behavior. (The error for your first code snippet above is "The operation overflows at compile time in checked mode." You aren't seeing a runtime error.)
Upvotes: 2
Reputation: 1079
This is because of compile-time overflow checking of your code. The line
Console.WriteLine(int.MaxValue - int.MinValue);
would not actually error at runtime, it would simple write "-1", but due to overflow checking you get the compile error "The operation overflows at compile time in checked mode".
To get around the compile-time overflow checking in this case you can do:
unchecked
{
Console.WriteLine(int.MaxValue - int.MinValue);
}
Which will run fine and output "-1"
Upvotes: 15