views:

485

answers:

5

Hi,

I had this weird experience with problem number 10 on Project Euler (great site by the way). The assignment was to calculate the sum of all the prime numbers below two million.

I used an int for the sum, and my algorith produced an answer, but when i pasted it to verify the answer, it was wrong.

It turned out that the result was too big to fit in an int, but wouldn't this cause an overflow error or something? Instead, it just returned a value far off from the real answer.

When I changed the type to long, everything was hunky dory.

+22  A: 

C# integer operations don’t throw exceptions upon overflow by default. You can achieve that via the project settings, or by making the calculation checked:

int result = checked(largeInt + otherLargeInt);

Now the operation will throw.

The opposite is unchecked, which makes any operation explicitly unchecked. Obviously, this only makes sense when you’ve got checked operations enabled in the project settings.

Konrad Rudolph
Unless you're in debug mode, where I think int operations are checked by default.
Ant
Nope. I ran in debug mode when this occured.
erikric
Oh. I stand corrected. I was sure that my Project Euler projects told me about overflows in debug mode. :/
Ant
"Obviously, this only makes sense when you’ve got checked operations enabled in the project settings." ... or you want to evaluate an `unchecked` expression in a `checked` context. You can certainly nest the blocks.
Mehrdad Afshari
A: 

Overflow of int can't cause exception by its own, but it can be caused by the other code, that relates on the variable that will contain overflow result.

Edited: Sorry for such a quick and bad answer, I meant that addition can't cause exception by default. Only with checked.

Restuta
simply not true - it can cause! http://msdn.microsoft.com/en-us/library/6a71f45d.aspx `Integer arithmetic overflow either throws an OverflowException or discards the most significant bits of the result`. maybe interesting: `Decimal arithmetic overflow always throws an OverflowException.`
Andreas Niedermair
Yes, yes yes, I wrote this to fast =( Indeed I mean that it can't cause overflow exception by addition.
Restuta
it can by addition either. it all depends on whether it's vb or c# (basic (un)checked behaviour) or if you do some (un)check ...
Andreas Niedermair
I should wrote "by default", agree with the top answer here.
Restuta
you may want to edit your answer, so you get rid of the downvotes...
Andreas Niedermair
+4  A: 

In C# an OverflowException is not thrown (in VB the exception is thrown per default).

To get the excpetion you have to embed your code in a checked context:

byte value = 241;
checked
{
    try 
    {
        sbyte newValue = (sbyte) value;
        Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", 
            value.GetType().Name, value, 
            newValue.GetType().Name, newValue);
    }
    catch (OverflowException) 
    {
        Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue);
    }
}       

MSDN explains in more detail:

For the arithmetic, casting, or conversion operation to throw an OverflowException, the operation must occur in a checked context. By default, arithmetic operations and overflows in Visual Basic are checked; in C#, they are not. If the operation occurs in an unchecked context, the result is truncated by discarding any high-order bits that do not fit into the destination type.

0xA3
+1  A: 

i've already added a cmt, but it's maybe interesting for some of you:

msdn tells us:

Integer arithmetic overflow either throws an OverflowException or discards the most significant bits of the result

but

Decimal arithmetic overflow always throws an OverflowException.

also

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.

Andreas Niedermair
+1  A: 

By default, C# does not check for arithmetic overflow on integers. You can change this with the /checked compiler option or by enabling "Check for arithmetic overflow/underflow" in Visual Studio (project properties - Build - Advanced).

You can use checked and unchecked keywords to override the default on a case-by-case basis. If you rely on checking taking place in a piece of code, explicitly enabling it using checked would be a good idea.

int j = checked(i * 2);

checked
{
    int j = i * 2;
    // Do more stuff
}

Note that floating point operations never throw an OverflowException, and decimal operations always throw an OverflowException. See also C# operators.

Thorarin