Click here to Skip to main content
16,005,222 members
Home / Discussions / Visual Basic
   

Visual Basic

 
GeneralRe: Windows SDK error message Pin
DaveC4269139-Sep-05 8:43
DaveC4269139-Sep-05 8:43 
QuestionVBer new to VB.net - handles divide by zero? Pin
DaveC42691318-Aug-05 10:35
DaveC42691318-Aug-05 10:35 
AnswerRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus18-Aug-05 15:09
protectorChristian Graus18-Aug-05 15:09 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Dave Kreskowiak19-Aug-05 6:48
mveDave Kreskowiak19-Aug-05 6:48 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus21-Aug-05 13:31
protectorChristian Graus21-Aug-05 13:31 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Dave Kreskowiak21-Aug-05 18:13
mveDave Kreskowiak21-Aug-05 18:13 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus21-Aug-05 18:15
protectorChristian Graus21-Aug-05 18:15 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Dave Kreskowiak22-Aug-05 6:49
mveDave Kreskowiak22-Aug-05 6:49 
After doing a little code and IL research and going back to the VB.NET docs on mathematical operators, all has become crystal clear. There are TWO division operators in VB.NET. Click here[^] for the docs, or just read on...

The normal one, that we're all used to using in any language, is "/". Well, in VB.NET, this operator is only used to divide two floating point numbers. The operator is defined for both the Single and Double types and also the Decimal type.

The Single and Double types are evaluated using standard IEEE 754 rules. Nothing new here, it's what we've been using for decades in C/C++ on floating point values and where our "interpretation" problem comes in while evaluating the original posters n1/n2 expression.

The Decimal type is a little different. If the right-hand operand is 0, the a System.DivideByZeroException is thrown. If the resulting value is too large to hold in the Decimal type a System.Overflow exception is thrown. If the resulting value is too small, then the Decimal type result will be 0.

The second division operator in VB.NET is "\" and is reserved for integer division using the VB.NET Byte, Short, Integer, and Long types. This is the division that the equivilent C# code is doing when comparing VISUALLY identical VB.NET and C# code using integer operands!

Now, according to MSDN:
"According to normal operator resolution rules, regular division purely between operands of types such as Byte, Short, Integer, and Long would cause both operands to be converted to type Decimal. However, when doing operator resolution on the division operator when neither type is Decimal, Double is considered narrower than Decimal. This convention is followed because Double division is more efficient than Decimal division."

Keeping that statement in mind, here's the proof of what's going on with the OP's code:

This is the test function code for VB.NET:
Dim n1, n2 As Integer
n1 = Convert.ToInt32("32")
n2 = Convert.ToInt32("0")
Console.WriteLine(n1 / n2)

The output is the string "Infinity". Something C# and C/C++ coders wouldn't expect to see.

The test function in C# is:
int n1;
int n2;
n1 = Convert.ToInt32(@"32");
n2 = Convert.ToInt32(@"0");
Console.WriteLine(n1 / n2);

This throws a DivideByZeroException on the Console.WriteLine call. No surprise there.

The difference (and proof) is in the IL.

First, both functions call the same conversion method to convert a string to an IL int32 type. The IL code appears to be the same between the two. Both generate:
.maxstack 2
.locals init ([0] int32 n1,
              [1] int32 n2)
IL_0000:  nop
IL_0001:  ldstr      "32"
IL_0006:  call       int32 [mscorlib]System.Convert::ToInt32(string)
IL_000b:  stloc.0
IL_000c:  ldstr      "0"
IL_0011:  call       int32 [mscorlib]System.Convert::ToInt32(string)
IL_0016:  stloc.1

Nothing surprising here. Both functions do exactly the same thing with exactly the same data types.
Both calls to convert are followed up by storing the resulting int32's into their appropriate storage locations.

The problem is in the division expression. The C# IL is:
IL_0017:  ldloc.0
IL_0018:  ldloc.1
IL_0019:  div
IL_001a:  call       void [mscorlib]System.Console::WriteLine(int32)
IL_001f:  nop
IL_0020:  ret

Simple enough. Load the int32 in location 0 onto the eval stack, then load the int32 in location 1 onto the eval stack. Do a divide operation on those two integers (int32 / int32). Call Console.WriteLine with the result.

The VB.NET IL is VERY different using the exact same character for the operator, but it has a different function. Using "/", the expression isn't evaluated as an int32 / int32. Both operands are first converted to IL float64's (or System.Double type) before the division operation. We all know the results of storing and operating on floating-point numbers in IEEE 754 format... Anyway, this is the VB.NET IL:
IL_0017:  ldloc.0
IL_0018:  conv.r8    <- Converts the value at the top of the eval stack to float64!!
IL_0019:  ldloc.1
IL_001a:  conv.r8    <- Converts the value at the top of the eval stack to float64!!
IL_001b:  div        <- IEEE 754 rules are different than integer division rules!
IL_001c:  call       void [mscorlib]System.Console::WriteLine(float64)
IL_0021:  nop
IL_0022:  nop
IL_0023:  ret


Now, change the VB.NET code to:
Dim n1, n2 As Integer
n1 = Convert.ToInt32("32")
n2 = Convert.ToInt32("0")
Console.WriteLine(n1 \ n2)

Of course, the resulting division IL code now falls in line with the expected C# IL code:
IL_0017:  ldloc.0
IL_0018:  ldloc.1
IL_0019:  div
IL_001a:  call       void [mscorlib]System.Console::WriteLine(int32)
IL_001f:  nop
IL_0020:  ret

If the OP changes the operator in his expression from "/" to "\", it'll do exactly the same thing as the equivilent c# code.

BTW: This testing was done on C# 2005 and VB.NET 2005, Beta 2.

This has been a public service announcement. We now return you to your regularly scheduled program...


RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome

GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus22-Aug-05 11:47
protectorChristian Graus22-Aug-05 11:47 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Dave Kreskowiak23-Aug-05 2:13
mveDave Kreskowiak23-Aug-05 2:13 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus23-Aug-05 13:23
protectorChristian Graus23-Aug-05 13:23 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
progload21-Aug-05 19:03
progload21-Aug-05 19:03 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus21-Aug-05 19:16
protectorChristian Graus21-Aug-05 19:16 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
progload21-Aug-05 21:06
progload21-Aug-05 21:06 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus22-Aug-05 11:43
protectorChristian Graus22-Aug-05 11:43 
AnswerRe: VBer new to VB.net - handles divide by zero? Pin
Daniel132418-Aug-05 16:15
Daniel132418-Aug-05 16:15 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus18-Aug-05 17:09
protectorChristian Graus18-Aug-05 17:09 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Daniel132418-Aug-05 17:25
Daniel132418-Aug-05 17:25 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
Christian Graus18-Aug-05 17:32
protectorChristian Graus18-Aug-05 17:32 
AnswerRe: VBer new to VB.net - handles divide by zero? Pin
progload18-Aug-05 19:38
progload18-Aug-05 19:38 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
DaveC42691319-Aug-05 3:27
DaveC42691319-Aug-05 3:27 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
progload19-Aug-05 3:50
progload19-Aug-05 3:50 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
DaveC42691319-Aug-05 4:24
DaveC42691319-Aug-05 4:24 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
progload19-Aug-05 4:53
progload19-Aug-05 4:53 
GeneralRe: VBer new to VB.net - handles divide by zero? Pin
DaveC42691319-Aug-05 5:20
DaveC42691319-Aug-05 5:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.