Does C# Handle Arithmetic Overflows Properly?

I'm not sure if this is a feature or a bug, but it certainly bugs me.

I'm preparing a training module for programming in C# and found something odd. I'm not sure whether someone already found this out but C# and VB seems to have a very different way of handling overflows in arithmetic operations.

In this case, VB seems to be handling it in the proper way.

The topic I was doing was about recursive functions, and the most common recursive function example is the Factorial function:

C#:

protected static int Factorial (int n)
{
if (n<2) return 1;
return n * Factorial(n - 1);
}
VB:

Protected Shared Function Factorial(ByVal n As Integer) As Integer
If (n < 2) Then Return 1
Return n * Factorial (n - 1)
End Function

Testing both functions with various values of n (and it's not a long list), the results are as follows:

n C# VB Actual
0 1 1 1
1 1 1 1
2 2 2 2
3 6 6 6
... ... ... ...
12 479001600 479001600 479001600
13 1932053504 Exception 6227020800
14 1278945280 " 87178291200
15 2004310016 " 1307674368000
16 2004189184 " 20922789888000
17 -288522240 " 355687428096000

These results were obtained using Visual Studio 2005.

By n = 13 C# was already spitting out incorrect values, while VB was throwing exceptions which C# ought to be also doing. By n = 17, C# even came up with a negative value.

It becomes clear now: C# was, instead of throwing overflow exceptions where the result of the function exceeds the MaxValue of the System.Int32 datatype, actually accepting the answer and most likely chopping off the lead bits of the proper answer. This becomes evident with n = 17, where apparently the sign bit of System.Int32 incorrectly reflected that of a negative number.

Better try it out yourself.

Tags: , , , ,

2 Responses to “Does C# Handle Arithmetic Overflows Properly?”

  1. jong.net says:

    I tried writing the recursion code in both VB.NET and C# in 2.0 framework and the exact results appear. Not unless, we put, the return statements on the checked statements, C# won’t raise an overflow exception.

  2. LaTtEX says:

    I recently found out that this is actually a compiler option: you could tell the compiler to either ignore or raise exceptions for overflows.

    So it’s not C#’s fault. :)

Leave a Reply