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)VB:
{
if (n<2) return 1;
return n * Factorial(n - 1);
}
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: .NET, C#, Programming Languages, Visual Basic, Visual Studio 2005
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.
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.