I ran a program in .Net 3.5 using C# which works fine
try
{
int i = 2147483647;
Console.WriteLine((i * 100 / i).ToString());
Console.ReadLine();
}
catch (Exception)
{
throw;
}
When I run this program in C#, I don't get an exception (it outputs "0"). But when I run this program in VB.Net it results in "Arithmetic operation resulted in an overflow"
exception
Try
Dim i As Integer = 2147483647
Console.WriteLine((i * 100 / i).ToString())
Console.ReadLine()
Catch ex As Exception
Throw
End Try
Why the different behavior between these two languages?
Perhaps looking at the IL will clarify... Simplifying your code a bit:
C#:
int i = 2147483647;
int v = (i * 100 / i);
generates the following IL:
IL_0001: ldc.i4 FF FF FF 7F
IL_0006: stloc.0 // i
IL_0007: ldloc.0 // i
IL_0008: ldc.i4.s 64
IL_000A: mul
IL_000B: ldloc.0 // i
IL_000C: div
IL_000D: stloc.1 // v
while the VB version:
Dim i As Integer = 2147483647
Dim v As Integer
v = i * 100 / i
generates this IL, slightly different:
IL_0001: ldc.i4 FF FF FF 7F
IL_0006: stloc.0 // i
IL_0007: ldloc.0 // i
IL_0008: ldc.i4.s 64
IL_000A: mul.ovf
IL_000B: conv.r8
IL_000C: ldloc.0 // i
IL_000D: conv.r8
IL_000E: div
IL_000F: call System.Math.Round
IL_0014: conv.ovf.i4
IL_0015: stloc.1 // v
As you can see, VB is calling mul.ovf
, which is "multiply, and check for overflow", and C# is calling mul
which does not check for overflow.
Perhaps it doesn't answer your question as to why C# does it one way and VB the other, but at least it answers why it is happening. :)
Edit: see the answer by aquinas to get the "why".
Try changing your program to this:
try {
checked {
int i = 2147483647;
Console.WriteLine((i * 100 / i).ToString());
Console.ReadLine();
}
}
catch (Exception) {
throw;
}
C# doesn't automatically perform arithmetic checking by default. However, if you go to project properties...Build Tab..Advanced..."[X] Check For Arithmetic overflow/underflow" then you will get the same behavior as VB.NET by default.
The output is different because the VB code you posted is not equivalent to the C# code. The correct conversion is:
Console.WriteLine((i * 100 \ i).ToString())
Note that C# performs integer (truncating) division on integers, while in VB you have to use the integer division operator '\\' to do the same integer division.
(update: even when using the correctly converted integer division operator, I also get the same exception in my test, so obviously it's not just about the operator).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.