以下两个表达式均为True
:
CInt(3.5) = Math.Round(3.5, MidpointRounding.AwayFromZero)
CInt(-3.5) = Math.Round(-3.5, MidpointRounding.AwayFromZero)
我意识到Math.Round返回Double
,但即使使用Integer
,我也可以在相同的上下文中使用Option Strict On
。那么,是否有人希望使用Math.Round(..., MidpointRounding.AwayFromZero)
而不是较短的CInt
?
P.S。同一主题上有一个question(我也问过),但问题很严重,因此,答案并没有解决真正的问题。
答案 0 :(得分:1)
在给出的示例中,结果为true,但如果将数字更改为4.5,则不是。
CInt(4.5) = Math.Round(4.5, MidpointRounding.AwayFromZero) 'False
CInt使用MidpointRounding.ToEven舍入。如果没有为Math.Round提供舍入模式,则使用MidpointRounding.ToEven。
答案是了解每种方法的作用并使用适当的方法。
答案 1 :(得分:0)
CInt(Double)
被编译为隐式强制转换,调用默认的Math.Round(Double)
并将结果转换为Integer
,因此使用Math.Round(Double, MidpointRounding.AwayFromZero)
代替CInt(Double)
的主要原因将是
MidpointRounding.AwayFromZero
四舍五入而不是默认的MidpointRounding.ToEven
四舍五入System.OverflowException
(任何小于Integer
或大于Integer.MinValue
的内容,例如Integer.MaxValue
),请Dim d = 2 ^ 31
CInt(1.5)
在C#中不小心转换为(int)1.5
,则可能会发生小的舍入错误。在VB.Net中,CInt(1.5)
为2,但在c#(int)1.5
中为1。从
生成的CIL字节码(在VS 2010 .NET 3.5中)Dim d As Double = 2.5
Dim i1 As Integer = CInt(d) ' 2
Dim i2 As Integer = CType(d, Integer) ' 2
Dim i3 As Integer = d ' 2
Dim d2 = Int(d) ' 2.0
ildasm.exe中的是:
IL_000f: ldc.r8 2.5
IL_0018: stloc.0
IL_0019: ldloc.0
IL_001a: call float64 [mscorlib]System.Math::Round(float64)
IL_001f: conv.ovf.i4
IL_0020: stloc.2
IL_0021: ldloc.0
IL_0022: call float64 [mscorlib]System.Math::Round(float64)
IL_0027: conv.ovf.i4
IL_0028: stloc.3
IL_0029: ldloc.0
IL_002a: call float64 [mscorlib]System.Math::Round(float64)
IL_002f: conv.ovf.i4
IL_0030: stloc.s i3
IL_0032: ldloc.0
IL_0033: call float64 [Microsoft.VisualBasic]Microsoft.VisualBasic.Conversion::Int(float64)
IL_0038: stloc.1
表明3次转换编译为默认Math.Round(Double)
和conv.ovf.i4
整数转换的同一次调用。