views:

390

answers:

4

What's up with this, anyway? I do a simple multiplication:

Int64 x = 11111111111;
Int64 y = 11111111111;
Int64 z = x * y;

And at the end of the multiplication, z shows a value of:

-5670418394979206991

This has clearly overflowed, but no exception is raised. I'd like one to be raised, but...

Note that this is on Windows Phone 7, but I don't think this has any bearing on the issue. Or does it?

+20  A: 

Check it:

checked
{
    Int64 x = 11111111111;
    Int64 y = 11111111111;
    Int64 z = x * y;
}
Darin Dimitrov
Bingo! Learn something new every day, I does! Thanks. And thank goodness for SO.
Cyberherbalist
+6  A: 

Try:

checked
{
    Int64 x = 11111111111;
    Int64 y = 11111111111;
    Int64 z = x * y;
}
IVlad
+5  A: 

Compiler assumes you want to do it that way and proceed with the Overflow. If overflow needs to be considered as exception for the operation, wrap the operation around checked and it will throw an exception at runtime.

checked
{
    Int64 x = 11111111111;
    Int64 y = 11111111111;
    Int64 z = x * y;
}

System.OverflowException: An exception of type System.OverflowException was thrown.

this. __curious_geek
+22  A: 

You can use a checked block as pointed out already by other answers:

checked
{
    long x = 11111111111;
    long y = 11111111111;
    long z = checked(x * y);
    // ...
}

Which results in an exception:

OverflowException: Arithmetic operation resulted in an overflow.

If you are just doing a single operation where you need checking you can use a checked expression instead:

long x = 11111111111;
long y = 11111111111;
long z = checked(x * y);

You can also set the /checked compiler option to have the default be checked.

To set this compiler option in the Visual Studio development environment:

  1. Open the project's Property Pages dialog box. For details, see Setting Visual C# Project Properties.
  2. Click the Configuration Properties folder.
  3. Click the Build property page.
  4. Modify the Check for Arithmetic Overflow/Underflow property.

If you change the default to checked you can use unchecked blocks or expressions to get the unchecked behaviour again.

Mark Byers
Note that the reason that unchecked is the default is because (1) 99% of the time integer arithmetic is nowhere near the boundaries, and (2) checked arithmetic is WAY slower. This is one of the rare cases where the design of C# chooses dangerous-by-default for performance reasons.
Eric Lippert
The x86 jitter uses a simple jno, branch prediction is always good, can't cost more than a single cycle.
Hans Passant
Not that it was necessarily relevant to the design of C# but in this specific case we're talking about ARM. The behaviour of the x86 jitter is somewhat academic
Stewart