VB.NET与C#整数除法的区别

80

有人可以解释一下为什么这两个代码片段表现出不同的结果吗?

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

7
在VB.NET中,两个整数pi进行除法运算p / i的结果是一个双精度浮点数Double,然后被转换为整数类型Integer。参考链接:https://dev59.com/pHI-5IYBdhLWcg3wPFx2。 - BoltClock
2
如果你在使用VB.NET,你真的应该打开Option Strict选项 - 这样编译器就会因为精度损失而生成一个错误。 - Ian Horwill
5个回答

84

当您查看这两个代码片段所生成的IL代码时,您会意识到VB.NET首先将整数值转换为双精度浮点数,应用除法,然后在它被转换回Int32并存储在y中之前四舍五入结果。

C#则不这样做。

VB.NET的IL代码:

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_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

在VB中,进行"正常的"整数除法需要使用反斜杠:p \ i。


17
一个简单问题的耐人寻味的精致回答。 - Rick Sladkey
+1。感谢您清晰地解释了它 : )。只是好奇微软是否有计划在未来的 .net 发布中消除这些语言特定的问题? - Sandeep G B
4
@Sandeep:我不认为他们会改变这种行为,因为它不仅在VB.NET中这样工作,而且在以前的版本中也是如此。这意味着VB程序员习惯于这种行为,并且实际上期望它。 - Christian
6
我们可以查看VB语言规范手册。在VB中,/始终表示浮点除法,而\\表示整数除法。在我看来,通过阅读手册比通过阅读编译器生成的IL更快地学习VB。 - MarkJ

78

在VB中,要进行整数除法,需要反斜杠:

Dim y As Integer = p \ i

否则在进行除法运算时将被转换为浮点数,然后在赋值给y前四舍五入并强制转换为整型。


3
“这种行为是有意设计的。” VB 10 语言规范 第 11.13.6 节。 - MarkJ
为什么C#没有实现这个功能让我感到困惑;明确、简洁、有用。可能是因为“他们”不喜欢VB具有一定的优雅性! - SteveCinq

16

8

"在 C# 和 VB 中,除法的执行方式不同。与其他基于 C 的语言一样,当两个操作数都是整数字面值、整数变量(或整数常量)时,C# 会截断除法结果。在 VB 中,您必须使用整数除法运算符 (\) 才能获得类似的结果。"

来源


-4
在C#中,当分子和分母都是整数时,使用/进行整数除法。而在VB.Net中,'/'会导致浮点数除法,因此在VB.Net中进行整数除法需要使用\。请参考MSDN post

1
不,这是不正确的。请查看其他答案以获取详细信息。 - Cody Gray
  1. 这不适用;它不能解释问题中讨论的行为。
  2. 我为什么要在意互联网上其他人有相同的误解?我无论如何都不能对那个答案进行负面评价。
  3. 即使这是正确的,抄袭别人的答案内容而没有注明出处,应该给予-1分。
- Cody Gray
我相当长时间以前看到了这篇帖子,所以我回答了它,显然不可能记得在互联网上阅读的所有链接。 - FIre Panda
那么,你不应该记住确切的措辞来回答它。无论如何,既然你已经更新了你的答案以匹配@Oded的答案,我真的不确定它有什么用处。 - Cody Gray
1
嗯,我承认在发布前应该先验证答案。 - FIre Panda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接