2016-11-18 21 views
0

下面的表達式兩者都是True在什麼情況下Math.Round(...,MidpointRounding.AwayFromZero)比CInt更可取?

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(我也問過),但這個問題被嚴重問到,結果,答案沒有解決真正的問題。

回答

1

在給出的例子中,結果是正確的,但如果將數字更改爲4.5,則它們不是。

CInt(4.5) = Math.Round(4.5, MidpointRounding.AwayFromZero) 'False 

CInt使用MidpointRounding.ToEven四捨五入。如果沒有爲Math.Round MidpointRounding.ToEven提供舍入模式。

答案是瞭解每種方法的作用,並使用適當的方法。

+0

因此,如果說使用'Math.Round(...,MidpointRounding.ToEven)'而不是'CInt',是不是真的會這麼說? – AlwaysLearning

+0

如果你有兩種方法可以完成同樣的事情,那它有什麼不同?中頻性能是一個問題,然後選擇更快的。 – dbasnett

0

CInt(Double)被編譯爲調用默認Math.Round(Double),並將結果轉換爲Integer隱式轉換,因此主要理由使用Math.Round(Double, MidpointRounding.AwayFromZero)代替CInt(Double)

  • 使用MidpointRounding.AwayFromZero四捨五入,而不是默認MidpointRounding.ToEven四捨五入
  • 避免System.OverflowException當結果不適合Integer(小於Integer.MinValue或大於Integer.MaxValueDim d = 2^31
  • 如果VB.Net中的CInt(1.5)在C#中被不小心轉換爲(int)1.5,則可能發生小的舍入錯誤。在VB.Net CInt(1.5)是2,但在c#(int)1.5是1

ildasm.exe

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 

產生(在VS 2010 .NET 3.5)的CIL字節碼是:

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整數轉換。

+0

當'CInt'拋出,但Math.Round成功時,會有什麼樣的例子? – AlwaysLearning

+0

小於「Integer.MinValue」或大於「Integer.MaxValue」的任何值,例如Dim d = 2^31。 'CInt(2^31)'甚至不會編譯,但是'CInt(2^31 - 1)'會。僅供參考,「Double.MaxValue」大約是「Integer.MaxValue」的299倍 – Slai

相關問題