80

Anyone care to explain why these two pieces of code exhibit different results?

VB.NET v4.0

Dim p As Integer = 16
Dim i As Integer = 10
Dim y As Integer = p / i
//Result: 2

C# v4.0

int p = 16;
int i = 10;
int y = p / i;
//Result: 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Maxim Gershkovich
  • 45,951
  • 44
  • 147
  • 243
  • 7
    It seems in VB.NET, `p / i` on two `Integer`s results in a `Double` http://stackoverflow.com/questions/1953164/why-do-the-division-operators-behave-differently-in-vb-net-and-c which then gets squished to an `Integer`. – BoltClock May 16 '11 at 05:53
  • 2
    If you're working in VB.NET you really should turn Option Strict on - then the compiler would have generated an error because of the loss of precision. – Ian Horwill Mar 28 '12 at 16:48

5 Answers5

84

When you look at the IL-code that those two snippets produce, you'll realize that VB.NET first converts the integer values to doubles, applies the division and then rounds the result before it's converted back to int32 and stored in y.

C# does none of that.

VB.NET IL Code:

IL_0000:  ldc.i4.s    10 
IL_0002:  stloc.1     
IL_0003:  ldc.i4.s    0A 
IL_0005:  stloc.0     
IL_0006:  ldloc.1     
IL_0007:  conv.r8     
IL_0008:  ldloc.0     
IL_0009:  conv.r8     
IL_000A:  div         
IL_000B:  call        System.Math.Round
IL_0010:  conv.ovf.i4 
IL_0011:  stloc.2     
IL_0012:  ldloc.2     
IL_0013:  call        System.Console.WriteLine

C# IL Code:

IL_0000:  ldc.i4.s    10 
IL_0002:  stloc.0     
IL_0003:  ldc.i4.s    0A 
IL_0005:  stloc.1     
IL_0006:  ldloc.0     
IL_0007:  ldloc.1     
IL_0008:  div         
IL_0009:  stloc.2     
IL_000A:  ldloc.2     
IL_000B:  call        System.Console.WriteLine

The "proper" integer division in VB needs a backwards slash: p \ i

Peter Rankin
  • 713
  • 1
  • 6
  • 29
Christian
  • 4,261
  • 22
  • 24
  • 17
    A refreshingly sophisticated answer to a simple question. – Rick Sladkey May 16 '11 at 06:07
  • +1. Thanks for explaining it neatly :). Just curious to know if Microsoft is having plans to neutralize these language specific things in the future releases of .net? – Sandeep G B May 16 '11 at 06:11
  • 4
    @Sandeep: I don't think they'll change that behaviour as it not only works that way in VB.NET but also in previous versions. That means VB programmers are used to this behaviour and they actually expect it. – Christian May 16 '11 at 06:16
  • 6
    We *could* look at the [VB language specification](http://msdn.microsoft.com/en-us/library/ms234437.aspx) or the [manual](http://msdn.microsoft.com/en-us/library/0e16fywh.aspx). In VB `/` always means floating-point division and `\\` means integer division. IMHO it's quicker to learn VB by reading the manual rather than by reading the IL produced by the compiler. – MarkJ May 16 '11 at 14:42
78

In VB, to do integer division, reverse the slash:

Dim y As Integer = p \ i

otherwise it is expanded to floating-point for the division, then forced back to an int after rounding when assigned to y.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 3
    +1. "This behaviour is by design" [VB 10 language specification](http://msdn.microsoft.com/en-us/library/ms234437.aspx) section 11.13.6 – MarkJ May 16 '11 at 14:37
  • And why this isn't implemented in c# confounds me; clear, concise, useful. Probably 'they' just don't like the idea that VB has some elegance! – SteveCinq Aug 30 '18 at 19:11
16

VB.NET integer division operator is \, not /.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
8

"Division is performed differently in C# and VB. C#, like other C-based languages truncates the division result when both operands are integer literals or integer variables (or integer constants). In VB, you must use the integer division operator (\) to get a similar result."

Source

lance
  • 16,092
  • 19
  • 77
  • 136
-4

In C#, integer division is applied with / when both numerator and denomenator are integers. Whereas, in VB.Net '/' results in floating point divsion, so for integer division in VB.Net use \. Have a look at this MSDN post.

FIre Panda
  • 6,537
  • 2
  • 25
  • 38
  • 1
    No, this is incorrect. See the other answers for details. – Cody Gray - on strike May 16 '11 at 10:00
  • (In response to [this](http://social.msdn.microsoft.com/forums/en-US/vblanguage/thread/bfc0f300-5eba-4fad-8db6-e1612385a560/) justification offered by answerer in a now-deleted comment.) 1) That's inapplicable; it doesn't explain the behavior discussed in the question. 2) Why should I care that someone else on the Internet has the same misunderstanding? I can't downvote that answer anyway. 3) Even if this were correct, -1 for copying and pasting content from someone else's answer without attribution. – Cody Gray - on strike May 16 '11 at 10:12
  • I came across with the post quite a while ago, so I aswered it and obviously thats not possible to remember the links of whatever you read on the internet. – FIre Panda May 16 '11 at 10:16
  • Then it shouldn't be possible to remember the exact phrasing to use it in your answer. At any rate, now that you've updated your answer to match @Oded's, I'm not really sure what purpose it serves. – Cody Gray - on strike May 16 '11 at 10:17
  • 1
    Well, I accept I should have verified the answer before posting. – FIre Panda May 16 '11 at 10:20